背景
- 今天遇到了一个使用C++读取json格式文本文档的需求,在python中是十分简单的一个需求,没想到要在C++实现的时候却卡了壳弄了一个下午找不到方法,特此记录一下解决方案,供各位参考
使用库
cJSON
cJSON是github开源的一个用于解析JSON字符串的库,相比其他库起来不需要麻烦的配置过程,只需要将一个.c文件和一个.h文件包含到源代码目录,在代码中
#include"cJSON.h"即可cJSON是使用链表来存储数据的,其访问方式很像一颗树。每一个节点可以有兄弟节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。只有节点是对象或数组时才可以有孩子节点
type是键(key)的类型,一共有7种取值,分别是:False,Ture,NULL,Number,String,Array,Object。若是Number类型,则valueint或valuedouble中存储着值。若期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。
string中存放的是这个节点的名字,可理解为key的名称
使用教程
在github上下载cJSON项目
将项目中的
cJSON.c与cJSON.h复制到自己的项目目录下,#include"cJSON.h"即可示例代码
123456using namespace std;78struct JsonTest9{10int id;11char cName[32];12float fValue;13};1415void TestJsonObject()16{1718//测试cJson 创建Json对象19JsonTest jsonObject = {1, "geekCode", 0.2f};20cJSON *root, *object;21char *result; //生成的结果22int i;2324root = cJSON_CreateObject();2526object = cJSON_CreateObject();27cJSON_AddNumberToObject(object, "id", jsonObject.id);28cJSON_AddStringToObject(object, "name", jsonObject.cName);29cJSON_AddNumberToObject(object, "value", jsonObject.fValue);3031cJSON_AddNumberToObject(root, "id", jsonObject.id);32cJSON_AddStringToObject(root, "name", jsonObject.cName);33cJSON_AddNumberToObject(root, "value", jsonObject.fValue);34cJSON_AddItemToObject(root, "object", object);3536result = cJSON_Print(root);37cJSON_Delete(root);38printf("生成Json:\n%s\n", result);3940//解析Json对象4142root = cJSON_Parse(result);43if (!root)44{45printf("Error before: [%s]\n", cJSON_GetErrorPtr());46return;47}48object = cJSON_GetObjectItem(root, "object");4950if (!object)51{52cJSON_Delete(root);53return;54}5556JsonTest objectJson;57JsonTest rootJson;5859//解析item60cJSON *item;61printf("解析过程:\n");62//解析到objectJson63item = cJSON_GetObjectItem(object, "id");64printf("Item: type=%d, key is %s, valueint=%d\n", item->type, item->string, item->valueint);65objectJson.id = item->valueint;66item = cJSON_GetObjectItem(object, "name");67printf("Item: type=%d, key is %s, valuestring=%s\n", item->type, item->string, item->valuestring);68strcpy(objectJson.cName, item->string);69item = cJSON_GetObjectItem(object, "value");70printf("Item: type=%d, key is %s, valuedouble=%2f\n", item->type, item->string, item->valuedouble);71objectJson.fValue = item->valuedouble;7273//解析到rootJson74item = cJSON_GetObjectItem(root, "id");75rootJson.id = item->valueint;76item = cJSON_GetObjectItem(root, "name");77strcpy(rootJson.cName, item->string);78item = cJSON_GetObjectItem(root, "value");79rootJson.fValue = item->valuedouble;8081//打印解析结果82printf("解析结果:\nroot:\n");83printf("\n\tid:%d\n\tname:%s\n\tvalue:%2f\n\t\n", rootJson.id, rootJson.cName, rootJson.fValue);84printf("\tobject:\n\t\tid:%d\n\t\tname:%s\n\t\tvalue:%2f\n", objectJson.id, objectJson.cName, objectJson.fValue);85}8687void TestRatingJson()88{89string jsonStr;90ifstream jsonFile;91jsonFile.open("../rating.json");92stringstream jsonStream;93jsonStream << jsonFile.rdbuf();94jsonFile.close();95jsonStr = jsonStream.str();9697cJSON *root;98cJSON *item;99cJSON *from;100string s;101root = cJSON_Parse(jsonStr.c_str());102103int size = cJSON_GetArraySize(root);104for (int i = 0; i < size; i++)105{106try107{108item = cJSON_GetArrayItem(root, i);109from = cJSON_GetObjectItem(item, "from");110s = from->valuestring;111std::cout << s << std::endl;112}113catch (const std::exception &e)114{115std::cerr << e.what() << '\n';116}117}118cJSON_Delete(root);119}120121int main()122{123// TestJsonObject();124TestRatingJson();125}其中rating.json文件可以前往这里下载