以下轉自:http://blog.csdn.net/ggicci/article/details/10600403
什么是Json?這個庫能做什么?
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. Json 是一種輕量的數據交換格式,和 XML 一樣在 Web 開發中非常常用。在 Ajax 的應用中,前台基本上會用到 JSON 作為數據交換格式,因為在 JS 里面可以通過 JSON.parse() 函數對 JSON 格式的字符串進行解析得到 JS 對象,通過這個 JS 對象可以輕松地獲取和修改里面的數據。而這個庫 ggicci::Json 可以像 JS 一樣通過解析獲得一個類似的 C++ 對象。通過這個 C++ 對象,你可以像使用 JS 一樣對數據進行獲取和修改,語法上基本類似。只不過 C++ 是強類型語言,所以當你在試圖用不一樣的數據類型去獲取里面的值的時候會拋異常。至於 C++ 是否需要 JSON 解析器,答案是肯定的,比如某個 CS 架構的程序,服務器端有某些頁面采用 web 技術輸出 JSON 數據,客戶端是 C++ 客戶端,它向這些頁面發送 HTTP 請求並接收到 JSON 數據,這些數據就需要解析以配合客戶端的使用。當然除非客戶端只是輸出這些字符串或者客戶端采用與 C++ 與 JS 混合編程方式,讓 JS 去處理這些數據。 項目地址和文檔 Github:https://github.com/ggicci/ggicci--json GGICCI:http://ggicci.me/works/json 文檔:http://ggicci.me/works/json/doc 看一個簡單例子 #include <iostream> #include "gci-json.h" using namespace std; using namespace ggicci; int main(int argc, char const *argv[]) { // Parse a string to get a Json object Json json = Json::Parse("{ \ \"id\": 18293, \ \"name\": \"Ggicci\", \ \"birthday\": [1991, 11, 10], \ \"man\": true \ }"); cout << "json = " << json << endl; cout << "-----------------------" << endl; cout << "id: " << json["id"] << endl; cout << "name: " << json["name"] << endl; cout << "birthday-year: " << json["birthday"][0] << endl; cout << "birthday-month: " << json["birthday"][1] << endl; cout << "birthday-day: " << json["birthday"][2] << endl; cout << "man: " << boolalpha << json["man"] << endl; cout << "-----------------------" << endl; json["name"] = "Mingjie Tang"; // add property: method 1 json["school"] = "Northwest A&F University"; // add property: method 2 json.AddProperty("traits", Json::Parse("[]").Push("sympathetic").Push("independent")); cout << "json = " << json << endl; cout << "-----------------------" << endl; json["birthday"].Remove(0); json.Remove("id").Remove("school"); cout << "json = " << json << endl; return 0; } /* output: ----------------------- id: 18293 name: "Ggicci" birthday-year: 1991 birthday-month: 11 birthday-day: 10 man: true ----------------------- json = { "birthday": [ 1991, 11, 10 ], "id": 18293, "man": true, "name": "Mingjie Tang", "school": "Northwest A&F University", "traits": [ "sympathetic", "independent" ] } ----------------------- json = { "birthday": [ 11, 10 ], "man": true, "name": "Mingjie Tang", "traits": [ "sympathetic", "independent" ] } */ 如果你對 JSON 的處理比較熟悉(你可能會使用 JS 處理 JSON 數據),你會發現上面的代碼很好理解。
與 JS 的使用比較(語法層面上)
對於原始的 JSON 字符串 str: { "id": 1000, "name": "ggicci", "birthday": [1991, 11, 10] }
JS: var str = '{ "id": 1000, "name": "ggicci", "birthday": [1991, 11, 10] }';
C++: const char* str = "{\"id\": 1000, \"name\": \"ggicci\", \"birthday\": [1991, 11, 10] }";
| 功能 | JS 的 JSON 解析器 | ggicci::Json(下面假設已聲明使用命名空間 ggicci) |
| 解析並得到JSON對象 | var json = JSON.parse(str); |
Json json = Json::Parse(str); |
| 獲取Number | var id = json["id"]; |
int id = json["id"]; |
| 獲取String | var name = json["name"]; |
const char* name = json["name"];string name = json["name"]; |
| 獲取Array | var birthday = json["birthday"]; |
Json birthday = json["birthday"]; // 拷貝Json &birthday = json["birthday"]; // 引用Json *birthday = json["birthday"]; // 指針 |
| ggicci::Json 中獲取 null(需要通過 Json 對象,IsNull() 函數用來確定接收到的數據是否是 null) 獲取Object(需要通過 Json 對象) 獲取true,false(通過 bool 值就可以了) | ||
| 修改Number | json["id"] = 19214; |
json["id"] = 19214; |
| 修改String | json["name"] = "Mingjie Tang"; |
json["name"] = "Mingjie Tang"; |
| 修改Array | json["birthday"][2] = 11; |
json["birthday"][2] = 11; |
| 添加數據(Array) | json["birthday"].push(2013);json["birthday"].push("hello"); |
json["birthday"].Push(2013).Push("hello"); |
| 添加數據(Object) | json["man"] = true; |
json["man"] = true;json.AddProperty("man", true); |
| 刪除數據(Array) | use pop, unshift ... | json["birthday"].Remove(0); // 不能級聯 |
| 刪除數據(Object) | delete json["name"]; |
json.Remove("name").Remove("id"); // 可以級聯 |
| 獲取Object的所有Keys | // 復雜 |
vector<string> keys = json.Keys(); |
異常處理 解析異常 int main(int argc, char const *argv[]) { try { Json json = Json::Parse("[1, 2, 2, { \"id\": 183, \"name\": 'Ggicci' } ]"); } catch (exception& e) { cout << e.what() << endl; // SyntaxError: Unexpected token ' at pos 31 } return 0; } 在 Chrome 下利用 JS 的 JSON::parse() 函數解析拋出的異常: 數據獲取異常 int main(int argc, char const *argv[]) { try { Json json = Json::Parse("[1, 2, 3, 4]"); int first = json[0]; // no problem const char* second = json[1]; // cause exception } catch (exception& e) { cout << e.what() << endl; // OperationError: Illegal extract opeartion from Number to String } return 0; } 非法操作異常 [cpp] view plain copy int main(int argc, char const *argv[]) { try { Json json = Json::Parse("[1, 2, 3, 4]"); json.AddProperty("name", "Ggicci"); // cause exception } catch (exception& e) { cout << e.what() << endl; // OperationError: Illegal add property opeartion on Array } return 0; } 類型檢測 [cpp] view plain copy int main(int argc, char const *argv[]) { Json json = Json::Parse("[1, \"hello\", { \"title\": null }, false ]"); json.IsArray(); // true json[0].IsNumber(); // true json[1].IsString(); // true json[2].IsObject(); // true json[2]["title"].IsNull(); //true json[3].IsBool(); // true if (json.IsArray()) { for (int i = 0; i < json.Size(); ++i) { switch (json[i].DataKind()) { case Json::kNumber: cout << "number: "; break; case Json::kString: cout << "string: "; break; case Json::kArray: cout << "array: "; break; case Json::kObject: cout << "object: "; break; case Json::kBool: cout << "bool: "; break; case Json::kNull: cout << "null: "; break; default: break; } cout << json[i] << endl; } } return 0; } /* output: number: 1 string: "hello" object: { "title": null } bool: false */
