背景
- 今天遇到了一个使用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"
即可示例代码
1
2
3
4
5
6
using namespace std;
7
8
struct JsonTest
9
{
10
int id;
11
char cName[32];
12
float fValue;
13
};
14
15
void TestJsonObject()
16
{
17
18
//测试cJson 创建Json对象
19
JsonTest jsonObject = {1, "geekCode", 0.2f};
20
cJSON *root, *object;
21
char *result; //生成的结果
22
int i;
23
24
root = cJSON_CreateObject();
25
26
object = cJSON_CreateObject();
27
cJSON_AddNumberToObject(object, "id", jsonObject.id);
28
cJSON_AddStringToObject(object, "name", jsonObject.cName);
29
cJSON_AddNumberToObject(object, "value", jsonObject.fValue);
30
31
cJSON_AddNumberToObject(root, "id", jsonObject.id);
32
cJSON_AddStringToObject(root, "name", jsonObject.cName);
33
cJSON_AddNumberToObject(root, "value", jsonObject.fValue);
34
cJSON_AddItemToObject(root, "object", object);
35
36
result = cJSON_Print(root);
37
cJSON_Delete(root);
38
printf("生成Json:\n%s\n", result);
39
40
//解析Json对象
41
42
root = cJSON_Parse(result);
43
if (!root)
44
{
45
printf("Error before: [%s]\n", cJSON_GetErrorPtr());
46
return;
47
}
48
object = cJSON_GetObjectItem(root, "object");
49
50
if (!object)
51
{
52
cJSON_Delete(root);
53
return;
54
}
55
56
JsonTest objectJson;
57
JsonTest rootJson;
58
59
//解析item
60
cJSON *item;
61
printf("解析过程:\n");
62
//解析到objectJson
63
item = cJSON_GetObjectItem(object, "id");
64
printf("Item: type=%d, key is %s, valueint=%d\n", item->type, item->string, item->valueint);
65
objectJson.id = item->valueint;
66
item = cJSON_GetObjectItem(object, "name");
67
printf("Item: type=%d, key is %s, valuestring=%s\n", item->type, item->string, item->valuestring);
68
strcpy(objectJson.cName, item->string);
69
item = cJSON_GetObjectItem(object, "value");
70
printf("Item: type=%d, key is %s, valuedouble=%2f\n", item->type, item->string, item->valuedouble);
71
objectJson.fValue = item->valuedouble;
72
73
//解析到rootJson
74
item = cJSON_GetObjectItem(root, "id");
75
rootJson.id = item->valueint;
76
item = cJSON_GetObjectItem(root, "name");
77
strcpy(rootJson.cName, item->string);
78
item = cJSON_GetObjectItem(root, "value");
79
rootJson.fValue = item->valuedouble;
80
81
//打印解析结果
82
printf("解析结果:\nroot:\n");
83
printf("\n\tid:%d\n\tname:%s\n\tvalue:%2f\n\t\n", rootJson.id, rootJson.cName, rootJson.fValue);
84
printf("\tobject:\n\t\tid:%d\n\t\tname:%s\n\t\tvalue:%2f\n", objectJson.id, objectJson.cName, objectJson.fValue);
85
}
86
87
void TestRatingJson()
88
{
89
string jsonStr;
90
ifstream jsonFile;
91
jsonFile.open("../rating.json");
92
stringstream jsonStream;
93
jsonStream << jsonFile.rdbuf();
94
jsonFile.close();
95
jsonStr = jsonStream.str();
96
97
cJSON *root;
98
cJSON *item;
99
cJSON *from;
100
string s;
101
root = cJSON_Parse(jsonStr.c_str());
102
103
int size = cJSON_GetArraySize(root);
104
for (int i = 0; i < size; i++)
105
{
106
try
107
{
108
item = cJSON_GetArrayItem(root, i);
109
from = cJSON_GetObjectItem(item, "from");
110
s = from->valuestring;
111
std::cout << s << std::endl;
112
}
113
catch (const std::exception &e)
114
{
115
std::cerr << e.what() << '\n';
116
}
117
}
118
cJSON_Delete(root);
119
}
120
121
int main()
122
{
123
// TestJsonObject();
124
TestRatingJson();
125
}
其中rating.json文件可以前往这里下载