Cpp Library 之 JsonCpp
JSONCPP是C++中的生成与解析JSON 字符串的一种实现。JSON(JavaScript Object Notation, JS 对象简谱)是一种人比较容易理解,机器也比较容易解析的轻量级的数据交换格式。
JSON的例子:
{"firstName": "Brett", "lastName": "McLaughlin"}
{ "country": "中国", "province": [{ "name": "黑龙江", "cities": { "city": ["哈尔滨", "大庆"] } }, { "name": "广东", "cities": { "city": ["广州", "深圳", "珠海"] } }, { "name": "台湾", "cities": { "city": ["台北", "高雄"] } }, { "name": "新疆", "cities": { "city": ["乌鲁木齐"] } }] }
参考:
https://www.jianshu.com/p/987e95cc79f4
http://www.cppblog.com/wanghaiguang/archive/2013/12/26/205020.html
https://blog.csdn.net/fishman_yinwang/article/details/78029309
https://blog.csdn.net/u010442009/article/details/38401351
https://blog.csdn.net/shaosunrise/article/details/84680602
下载JsonCpp的地址:https://github.com/open-source-parsers/jsoncpp
注意:1.x.x的版本要编译器支持C++11, 0.x.x的可以不支持。由于VS2013编译1.x.x 版本报错,故使用了 0.5.0 下载:http://sourceforge.net/projects/jsoncpp/
编译:下载并解压jsoncpp源代码后,你会得到文件夹jsoncpp-src-0.5.0,依次定位到jsoncpp-src-0.5.0/makefiles/vs71,里面就是VC++的项目文件了.你可以用VS打开jsoncpp.sln,里面有3个project:jsontest, lib_json和test_lib_json。
选择Debug编译 生成 json_vc71_libmtd.lib,选择Release编译 生成 json_vc71_libmt.lib 。
这里要注意的是:“运行lib_json项目前要设置一下c/c++-》代码生成-》运行库以便生成不一样的lib文件”
如果lib要用于MTd环境下,则设置为MTd;如果lib要用于MDd环境下,则设置为MDd
问题解决:
1. Release下使用lib库出现错误 ...src\lib_json\json_reader.cpp : fatal error C1083: 无法打开编译器生成的文件: “../../build/vs71/release/lib_json\json_reader.asm”: No such file or directory
1>LINK : fatal error LNK1257: 代码生成失败。
办法:修改生成静态库文件的工程的属性:路径为:菜单-项目-属性-配置属性-c/c++ - 输出文件-汇编程序输出:无列表。lib_json项目中汇编程序输出原配置为:带源代码的程序集(/FAs),改为:无列表生成即可。 参见 https://blog.csdn.net/daiafei/article/details/493070732. 新版的JsonCpp的使用,用reader.parse函数时,可能出现“Use CharReader and CharReaderBuilder instead”的错误,可以用 #pragma warning(disable:4996) 解决
这里是我编译好的:https://pan.baidu.com/s/1w3FosadxoRsQIrjUlPGM6A 提取码:du1c
#include <iostream> #include <string> #include "json/json.h" #pragma comment(lib,"./build/debug/lib_json/json_vc71_libmtd.lib") int main(void) { std::string strValue = "{\"key1\":\"value1\",\"array\":[{\"key2\":\"value2\"},{\"key2\":\"value3\"},{\"key2\":\"value4\"}]}"; Json::Reader reader;//json解析 Json::Value value;//表示一个json格式的对象 // 注意:当strJson中有单个 \ 字符(0x5c)时,解析失败。有 \n 可以。Big5编码的“許功蓋”里面含有0x5c可能解析不出来。 if (reader.parse(strValue, value))//解析出json放到json中区 { std::string out = value["key1"].asString(); std::cout << out << std::endl; const Json::Value arrayObj = value["array"];//迭代器 std::cout << "array:\n"; for (int i = 0; i < arrayObj.size(); i++) { out = arrayObj[i]["key2"].asString(); std::cout << '\t' << out; if (i != arrayObj.size() - 1) std::cout << std::endl;; } } getchar(); return 0; }
解析Json
自己写的解析,解析上面的 “中国”的JSON
#include <iostream> #include <fstream> #include <sstream> #include <string> #include "json/json.h" #if defined _DEBUG #pragma comment(lib,"./build/debug/lib_json/json_vc71_libmtd.lib") //#pragma comment(lib,"./build/debug/lib_json/json_vc71_libMDd.lib") #else #pragma comment(lib,"./build/release/lib_json/json_vc71_libmt.lib") //#pragma comment(lib,"./build/release/lib_json/json_vc71_libMD.lib") #endif int main(void) { //从一个json文件中读 reader.parse(ifile, root); 从json字符串读 reader.parse(sJson, root); std::ifstream ifile("testjson.txt",std::ios::binary); if (!ifile.is_open()) return -1; std::stringstream buffer; buffer << ifile.rdbuf(); std::string sJson(buffer.str()); ifile.seekg(0, std::ios::beg);//std::ios::beg=SEEK_SET=0 //移动到文件开头 Json::Reader reader; Json::Value root; //Json::Value是一种很重要的类型,可以代表任意类型。如int, string, object, array bool ret = reader.parse(ifile, root);//可以解析中文,但当有 \ (0x5c)时,可能会出错 if (!ret) return -2; std::string sCountry = root["country"].asString(); const Json::Value arr = root["province"]; for (size_t i = 0; i < arr.size(); ++i) { std::string sName = arr[i]["name"].asString(); const Json::Value obj = arr[i]["cities"]; const Json::Value arrCity = obj["city"]; for (size_t j = 0; j < arrCity.size(); ++j) { std::string sCity = arrCity[j].asString(); } } return 0; }
生成Json
#include <iostream> #include <fstream> #include <sstream> #include <string> #include "json/json.h" #if defined _DEBUG #pragma comment(lib,"./build/debug/lib_json/json_vc71_libmtd.lib") //#pragma comment(lib,"./build/debug/lib_json/json_vc71_libMDd.lib") #else #pragma comment(lib,"./build/release/lib_json/json_vc71_libmt.lib") //#pragma comment(lib,"./build/release/lib_json/json_vc71_libMD.lib") #endif int main(void) { Json::Value root, arrProvince, ObjCities, arrCity; Json::FastWriter writer; root["country"] = "中国"; arrCity[0u] = "哈尔滨"; arrCity[1] = "大庆"; ObjCities["city"] = arrCity; arrProvince[0u]["name"] = "黑龙江"; arrProvince[0u]["cities"] = ObjCities; arrCity.clear(); ObjCities.clear(); arrCity[0u] = "广州"; arrCity[1] = "深圳"; arrCity[2] = "珠海"; ObjCities["city"] = arrCity; arrProvince[1]["name"] = "广东"; arrProvince[1]["cities"] = ObjCities; arrCity.clear(); ObjCities.clear(); arrCity[0u] = "乌鲁木齐"; ObjCities["city"] = arrCity; arrProvince[2]["name"] = "新疆"; arrProvince[2]["cities"] = ObjCities; root["province"] = arrProvince; std::string sJson = writer.write(root); return 0; } /* 注意:生成的json,key是按字母排好序的,可能跟添加的顺序不相同;但不影响解析,解析直接用key值查找,仍然可以用上面的解析程序去解析 {"country":"中国","province":[{"cities":{"city":["哈尔滨","大庆"]},"name":"黑龙江"},{"cities":{"city":["广州","深圳","珠海"]},"name":"广东"},{"cities":{"city":["乌鲁木齐"]},"name":"新疆"}]} */
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。