JSON全稱為JavaScript ObjectNotation,它是一種輕量級的數據交換格式,易於閱讀、編寫、解析。jsoncpp是c++解析JSON串常用的解析庫之一。
jsoncpp中主要的類:
Json::Value:可以表示所有支持的類型,如:int , double ,string , object, array等。其包含節點的類型判斷(isNull,isBool,isInt,isArray,isMember,isValidIndex等),類型獲取(type),類型轉換(asInt,asString等),節點獲取(get,[]),節點比較(重載<,<=,>,>=,==,!=),節點操作(compare,swap,removeMember,removeindex,append等)等函數。
Json::Reader:將文件流或字符串創解析到Json::Value中,主要使用parse函數。Json::Reader的構造函數還允許用戶使用特性Features來自定義Json的嚴格等級。
Json::Writer:與JsonReader相反,將Json::Value轉換成字符串流等,Writer類是一個純虛類,並不能直接使用。在此我們使用 Json::Writer 的子類:Json::FastWriter(將數據寫入一行,沒有格式),Json::StyledWriter(按json格式化輸出,易於閱讀)
JsonCpp使用注意點:
1.對不存在的鍵獲取值會返回此類型的默認值。
2.通過key獲取value時,要先判斷value的類型,使用錯誤的類型獲取value會導致程序中斷。
3.獲取json數組中某一項key的value應該使用value[arraykey][index][subkey]獲取或循環遍歷數組獲取。
4.append函數功能是將Json::Value添加到數組末尾。
5.由於Jsoncpp解析非法json時,會自動容錯成字符類型。對字符類型取下標時,會觸發assert終止進程。
解決方法:啟用嚴格模式,讓非法的json解析時直接返回false,不自動容錯。這樣,在調用parse的時候就會返回false。
Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
判斷json字符串中是否存在某鍵值的幾種方法:
1.value.isMember("key"); //存在返回true,否則為false 2.value["sex"].isNull(); //為NULL返回1,否則為0
JsonCpp讀寫示例代碼:
#include <iostream> #include <sstream> #include <fstream> #include <json/json.h> void readJsonFromFile() { std::ifstream ifs; ifs.open("a.json"); std::stringstream buffer; buffer << ifs.rdbuf(); ifs.close(); auto str = buffer.str(); Json::Reader reader; Json::Value value; if (reader.parse(str, value)) { //節點判斷 std::cout << "value's empty:" << value.empty() << std::endl; std::cout << "name is string:" << value["name"].isString() << std::endl; std::cout << "age is string:" << value["age"].isString() << std::endl; //類型獲取 std::cout << "name's type:" << value["name"].type() << std::endl; std::cout << "like's type:" << value["like"].type() << std::endl; //類型轉換 //根據Key獲取值時最好判斷類型,否則解析會中斷 std::cout << "name:" << value["name"].asString() << std::endl; std::cout << "age:" << value["age"].asInt() << std::endl; //節點獲取 std::cout << value["job"] << std::endl; //[]方式獲取 std::cout << value.get("name", "dxx") << std::endl; //get方式獲取 std::cout << value.isMember("job") << std::endl; std::cout << "value's obj:" << value.isObject() << std::endl; std::cout << "like's obj:" << value["like"].isObject() << std::endl;
std::cout << "like.size:" << value["like"].size() << std::endl; std::cout << "like[0][food]:" << value["like"][0]["food"].asString() << std::endl; //節點操作 std::cout << "name compare age:" << value["name"].compare("age") << std::endl; value["name"] = "swduan"; //修改 value["address"] = "hz"; //增加 value["phone"] = "10086"; value.removeMember("age"); //刪除 value["like"][0]["sport"] = "game"; //往value["like"]中添加一項元素 Json::Value item; item["hate"] = "game"; value["like"].append(item); //value["like"]中再添加一維數組 std::cout << "value[\"like\"]'s size:" << value["like"].size() << std::endl; std::cout << "--------------------" << std::endl; std::cout << value.toStyledString() << std::endl; std::cout << "--------------------" << std::endl; auto all_member = value.getMemberNames(); for (auto member : all_member) { std::cout << member << std::endl; } std::cout << "--------------------" << std::endl; value.clear(); //清空元素 std::cout << value.toStyledString() << std::endl; } } void jsonWriteToFile() { Json::FastWriter write; Json::Value root; Json::Value item; Json::Value arrayObj; item["book"] = "c++"; item["food"] = "apple"; item["music"] = "ddx"; arrayObj.append(item); root["name"] = "dsw"; root["age"] = 18; root["like"] = arrayObj; //注意:這里不能用append,append功能是將Json::Value添加到數組末尾 auto str = root.toStyledString(); std::cout << str << std::endl; std::ofstream ofss; ofss.open("a.json"); ofss << str; ofss.close(); } int main() { jsonWriteToFile(); readJsonFromFile(); getchar(); return 0; }
輸出:

value's empty:0 name is string:1 age is string:0 name's type:4 like's type:6 name:dsw age:18 null "dsw" 1 value's obj:1 like's obj:0 like.size:1 like[0][food]:apple name compare age:1 value["like"]'s size:2 -------------------- { "address" : "hz", "job" : null, "like" : [ { "book" : "c++", "food" : "apple", "music" : "ddx", "sport" : "game" }, { "hate" : "game" } ], "name" : "swduan", "phone" : "10086" } -------------------- address job like name phone -------------------- {}