两种库解析、构造 JSON
2018-05-28 23:28 清晨、午后 阅读(374) 评论(0) 编辑 收藏 举报1.用CJSON库
1.1解析Json
需要解析的JSON文件:
{ "name":"Tsybius", "age":23, "sex_is_male":true, "partner": { "partner_name":"Galatea", "partner_age":21, "partner_sex_is_male":false }, "achievement":["ach1","ach2","ach3"] }
解析代码(层次解析法)
/* 读取JSON格式的文件到string */ ULONG_32 TMS_C_ReadJSONFile(const std::string ostrFileName, std::string &ostrJSON) { std::ifstream oInFile; oInFile.open(ostrFileName.data()); //将文件流对象与文件连接起来 std::string strText; while (getline(oInFile, strText)) { ostrJSON += strText; } oInFile.close(); return 0 ; }
int main() { //str 为从文件中读取到的值 std::string str = "{\"name\":\"Tsybius\",\"age\":23,\"sex_is_male\":true, \"partner\":{\"partner_name\":\"Galatea\",\"partner_age\":21,\"partner_sex_is_male\":false},\"achievement\":[\"ach1\",\"ach2\",\"ach3\"]}"; //转换为整个Json cJSON *returnjson = cJSON_Parse(str.c_str()); if (NULL == returnjson) { return 0; } // 获取根节点下的某个值 cJSON * name = cJSON_GetObjectItem(returnjson, "name"); if(NULL == name) { return 0; } std::string str1 = name->valuestring; std::cout << str1 << std::endl; // 获取子节点 cJSON * partner = cJSON_GetObjectItem(returnjson, "partner"); if(NULL == partner) { return 0; } // 获取子节点下的某个值 cJSON * partner_name = cJSON_GetObjectItem(partner, "partner_name"); if(NULL == partner_name) { return 0; } std::string str2 = partner_name->valuestring; std::cout << str2 << std::endl; // 获取子节点下的数组 cJSON * achievement = cJSON_GetObjectItem(returnjson, "achievement"); if(NULL == achievement) { return 0; } cJSON *pArrayItem = NULL; pArrayItem = cJSON_GetArrayItem(achievement, 0); std::string str3 = pArrayItem->valuestring; int i = cJSON_GetArraySize(achievement); //获取数组大小 cJSON_Delete(returnjson); // 注意cJSON的内存泄漏
system("pause"); return 0; }
1.2构造Json
#include <fstream> #include <string> #include <vector> #include "cJSON.h" int main() { int ulRet = 0; std::string ostrJSONFilePath1 = "F:\\1.txt"; //ulRet = TMS_C_ReadJSONFile(ostrJSONFilePath1); cJSON *pJsonVehicleInfo = NULL; //也可以先创建数组,然后添加元素,构造为数组对象 pJsonVehicleInfo = cJSON_CreateObject(); cJSON *vehicleList = NULL; cJSON_AddItemToObject(pJsonVehicleInfo, "MotorVehicleObjectList", vehicleList = cJSON_CreateArray()); cJSON *subdir = NULL; cJSON_AddItemToArray(vehicleList, subdir = cJSON_CreateObject()); cJSON_AddStringToObject(subdir, "MotorVehicleID", "2"); cJSON_AddNumberToObject(subdir, "InfoKind", 3); cJSON_AddStringToObject(subdir, "SourceID", "4"); cJSON_AddStringToObject(subdir, "TollgateID", "5"); cJSON *SubImageObject = NULL; cJSON_AddItemToObject(subdir, "SubImageObject", SubImageObject = cJSON_CreateObject()); cJSON *picList = NULL; cJSON_AddItemToObject(SubImageObject, "SubImageInfoList", picList = cJSON_CreateArray()); cJSON *sub = NULL; cJSON_AddItemToArray(picList, sub = cJSON_CreateObject()); cJSON_AddStringToObject(sub, "pic1", "pic1"); cJSON_AddStringToObject(sub, "pic2", "pic2"); sub = NULL; cJSON_AddItemToArray(picList, sub = cJSON_CreateObject()); cJSON_AddStringToObject(sub, "pic3", "pic3"); cJSON_AddStringToObject(sub, "pic4", "pic4"); /* JSON转为字符串 */ char * responeJSONbuffer = cJSON_Print(pJsonVehicleInfo); std::string ostrJSONFilePath = "F:\\3.txt"; std::ofstream oOutFile; oOutFile.open(ostrJSONFilePath.data()); oOutFile << responeJSONbuffer << std::endl; oOutFile.close(); cJSON_Delete(pJsonVehicleInfo); // 注意cJSON的内存泄漏,只需要释放根节点即可
system("pause"); return 0; }
构造后输出的文档
{ "MotorVehicleObjectList": [{ "MotorVehicleID": "2", "InfoKind": 3, "SourceID": "4", "TollgateID": "5", "SubImageObject": { "SubImageInfoList": [ { "pic1": "pic1", "pic2": "pic2" }, { "pic3": "pic3", "pic4": "pic4" } ] } }] }
2. 用jsoncpp.zip
2.1获取json第三方工具
下载 jsoncpp.zip ,解压后可在vs下建立新的工程进行编译,注意设置 配置熟悉》c/c++》代码生成》运行时库为MTd(使用该库的工程也这样设置),编译后将 lib 文件放入工程目录,将 jsoncpp\include整个文件放入工程中的文件(使用lib时需要引用该库文件文件的头文件)。
2.2 从文件中解析JSON
需要解析的JSON文件:
{ "name":"Tsybius", "age":23, "sex_is_male":true, "partner": { "partner_name":"Galatea", "partner_age":21, "partner_sex_is_male":false }, "achievement":["ach1","ach2","ach3"] }
方法1:整体解析法
#include <iostream> #include <fstream> #include "json/json.h" using namespace std; int main() { Json::Reader reader; Json::Value root; //从文件中读取 ifstream is; is.open("PersonalInfo.json", ios::binary); if(reader.parse(is,root)) { //读取根节点信息 string name = root["name"].asString(); int age = root["age"].asInt(); bool sex_is_male = root["sex_is_male"].asBool(); //读取子节点信息 string partner_name = root["partner"]["partner_name"].asString(); int partner_age = root["partner"]["partner_age"].asInt(); bool partner_sex_is_male = root["partner"]["partner_sex_is_male"].asBool(); //读取数组信息 cout << "Here's my achievements:" << endl; for(int i = 0; i < root["achievement"].size(); i++) { // 严重的bug, string ach = root["achievement"][0].asString(); 写成这样无法编译,如果索引是0,则必须用变量替代 string ach = root["achievement"][i].asString(); cout << ach << '\t'; } } is.close(); system("pause"); return 0; }
方法2:层次解析法,见CJSON库的使用
2.3将信息保存为JSON格式
code
#include <iostream> #include <fstream> #include "json/json.h" using namespace std; int main() { //根节点 Json::Value root; //根节点属性 root["name"] = Json::Value("Tsybius"); root["age"] = Json::Value(23); root["sex_is_male"] = Json::Value(true); //子节点 Json::Value partner; //子节点属性 partner["partner_name"] = Json::Value("Galatea"); partner["partner_age"] = Json::Value(21); partner["partner_sex_is_male"] = Json::Value(false); //子节点挂到根节点上 root["partner"] = Json::Value(partner); //数组形式 root["achievement"].append("ach1"); root["achievement"].append("ach2"); root["achievement"].append("ach3"); //数组对象 //Json::Value array; //array["arr1"] = Json::Value(1); //array["arr2"] = Json::Value(2); //root["achievement"].append(array); //可以直接将对象追加到数组中,构成[{...},{...}] 格式 //直接输出 cout << "FastWriter:" << endl; Json::FastWriter fw; cout << fw.write(root) << endl << endl; //缩进输出 cout << "StyledWriter:" << endl; Json::StyledWriter sw; cout << sw.write(root) << endl << endl; //输出到文件 ofstream os; os.open("PersonalInfo"); os << sw.write(root); os.close(); system("pause"); return 0; }
保存的文件 :
{ "achievement" : [ "ach1", "ach2", "ach3" ], "age" : 23, "name" : "Tsybius", "partner" : { "partner_age" : 21, "partner_name" : "Galatea", "partner_sex_is_male" : false }, "sex_is_male" : true }