转自:
https://blog.csdn.net/qq849635649/article/details/52678822
我在工作中一直使用的是rapidjson库,这是我在工作中使用该库作的一些整理,以读写下面的这段json字符串为例来进行整理,该字符串覆盖了平时使用的布尔类型、整型、浮点类型、结构体类型、字符串类型以及相对应的数组类型。
代码地址:https://git.oschina.net/zhaoyf/zhaoyf_csdn/tree/master/test_json
这时生成的目标json字符串
"Int": 1,
"Double": 12.0000001,
"String": "This is a string",
"Object": {
"name": "qq849635649",
"age": 25
"IntArray": [
"DoubleArray": [
"StringArray": [
"one",
"two",
"three"
"MixedArray": [
"one",
false,
12.005
"People": [
"name": "qq849635649",
"age": 0,
"sex": true
"name": "qq849635649",
"age": 10,
"sex": false
"name": "qq849635649",
"age": 20,
"sex": true
一、写json协议
1. 下面这段代码是我最喜欢用的一种方式,使用字符串缓冲器生成
1 #include "rapidjson/stringbuffer.h"
2 #include "rapidjson/writer.h"
3 #include <iostream>
4 #include <string>
6 using namespace std;
8 void Serialize_1()
10 rapidjson::StringBuffer strBuf;
11 rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
13 writer.StartObject();
15 //1. 整数类型
16 writer.Key("Int");
17 writer.Int(1);
19 //2. 浮点类型
20 writer.Key("Double");
21 writer.Double(12.0000001);
23 //3. 字符串类型
24 writer.Key("String");
25 writer.String("This is a string");
27 //4. 结构体类型
28 writer.Key("Object");
29 writer.StartObject();
30 writer.Key("name");
31 writer.String("qq849635649");
32 writer.Key("age");
33 writer.Int(25);
34 writer.EndObject();
36 //5. 数组类型
37 //5.1 整型数组
38 writer.Key("IntArray");
39 writer.StartArray();
40 //顺序写入即可
41 writer.Int(10);
42 writer.Int(20);
43 writer.Int(30);
44 writer.EndArray();
46 //5.2 浮点型数组
47 writer.Key("DoubleArray");
48 writer.StartArray();
49 for(int i = 1; i < 4; i++)
50 {
51 writer.Double(i * 1.0);
52 }
53 writer.EndArray();
55 //5.3 字符串数组
56 writer.Key("StringArray");
57 writer.StartArray();
58 writer.String("one");
59 writer.String("two");
60 writer.String("three");
61 writer.EndArray();
63 //5.4 混合型数组
64 //这说明了,一个json数组内容是不限制类型的
65 writer.Key("MixedArray");
66 writer.StartArray();
67 writer.String("one");
68 writer.Int(50);
69 writer.Bool(false);
70 writer.Double(12.005);
71 writer.EndArray();
73 //5.5 结构体数组
74 writer.Key("People");
75 writer.StartArray();
76 for(int i = 0; i < 3; i++)
77 {
78 writer.StartObject();
79 writer.Key("name");
80 writer.String("qq849635649");
81 writer.Key("age");
82 writer.Int(i * 10);
83 writer.Key("sex");
84 writer.Bool((i % 2) == 0);
85 writer.EndObject();
86 }
87 writer.EndArray();
89 writer.EndObject();
91 string data = strBuf.GetString();
92 cout << data << endl;
2. 接下来这种方式是我刚开始学习使用该库时网上收到的结果,使用不像上面那么方便
1 #include "rapidjson/document.h"
2 #include "rapidjson/stringbuffer.h"
3 #include "rapidjson/writer.h"
6 void Serialize_2()
8 rapidjson::Document doc;
9 doc.SetObject();
10 rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
12 //1. 整型类型
13 doc.AddMember("Int", 1, allocator);
15 //2. 浮点类型
16 doc.AddMember("Double", 12.00001, allocator);
18 //3. 字符串类型
19 //正确方式
20 string str= "This is a string";
21 rapidjson::Value str_value(rapidjson::kStringType);
22 str_value.SetString(str.c_str(), str.size());
23 if(!str_value.IsNull())
24 {
25 doc.AddMember("
String", str_value, allocator);
26 }
27 /**
28 * 注:以下方式不正确,可能成功,也可能失败,因为字符串写入json要重新开辟内存,
29 * 如果使用该方式的话,当数据是字符串常量的话是没问题的,如果为变量就会显示乱码,所
30 * 以为保险起见,我们显式的分配内存(无需释放)
31 */
32 //doc.AddMember("String", str.data(), allocator);
34 //4. 结构体类型
35 rapidjson::Value object(rapidjson::kObjectType);
36 object.AddMember("name", "qq849635649", allocator); //注:常量是没有问题的
37 object.AddMember("age", 25, allocator);
38 doc.AddMember("Object", object, allocator);
40 //5. 数组类型
41 //5.1 整型数组
42 rapidjson::Value IntArray(rapidjson::kArrayType);
43 IntArray.PushBack(10, allocator);
44 IntArray.PushBack(20, allocator);
45 IntArray.PushBack(30, allocator);
46 doc.AddMember("IntArray", IntArray, allocator);
48 //5.2 浮点型数组
49 rapidjson::Value DoubleArray(rapidjson::kArrayType);
50 DoubleArray.PushBack(1.0, allocator);
51 DoubleArray.PushBack(2.0, allocator);
52 DoubleArray.PushBack(3.0, allocator);
53 doc.AddMember("DoubleArray", DoubleArray, allocator);
55 //5.3 字符型数组
56 rapidjson::Value StringArray(rapidjson::kArrayType);
57 string strValue1 = "one";
58 string strValue2 = "two";
59 string strValue3 = "three";
60 str_value.SetString(strValue1.c_str(), strValue1.size());
61 StringArray.PushBack(str_value, allocator);
62 str_value.SetString(strValue2.c_str(), strValue2.size());
63 StringArray.PushBack(str_value, allocator);
64 str_value.SetString(strValue3.c_str(), strValue3.size());
65 StringArray.PushBack(str_value, allocator);
66 doc.AddMember("StringArray", StringArray, allocator);
68 //5.4 结构体数组
69 rapidjson::Value ObjectArray(rapidjson::kArrayType);
70 for(int i = 1; i < 4; i++)
71 {
72 rapidjson::Value obj(rapidjson::kObjectType);
73 obj.AddMember("name", "qq849635649", allocator);//注:常量是没有问题的
74 obj.AddMember("age", i * 10, allocator);
75 ObjectArray.PushBack(obj, allocator);
76 }
77 doc.AddMember("ObjectArray", ObjectArray, allocator);
79 rapidjson::StringBuffer strBuf;
80 rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
81 doc.Accept(writer);
83 string data = strBuf.GetString();
84 cout << data << endl;
下面是解析的代码,同样的,采用的依旧上面那个json字符串,分门别类的已经整理好
1 #include "rapidjson/document.h"
2 #include "rapidjson/stringbuffer.h"
3 #include "rapidjson/writer.h"
5 string data =
6 "{\"Int\":1,"
7 "\"Double\":12.0000001,"
8 "\"String\":\"This is a string\","
9 "\"Object\":{\"name\":\"qq849635649\",\"age\":25},"
10 "\"IntArray\":[10,20,30],"
11 "\"DoubleArray\":[1.0,2.0,3.0],"
12 "\"StringArray\":[\"one\",\"two\",\"three\"],"
13 "\"MixedArray\":[\"one\",50,false,12.005],"
14 "\"People\":[{\"name\":\"qq849635649\",\"age\":0,\"sex\":true},"
15 "{\"name\":\"qq849635649\",\"age\":10,\"sex\":false},"
16 "{\"name\":\"qq849635649\",\"age\":20,\"sex\":true}]}";
18 void parse() {
19 //创建解析对象
20 rapidjson::Document doc;
21 //首先进行解析,没有解析错误才能进行具体字段的解析
22 if(!doc.Parse(data.data()).HasParseError())
23 {
24 //1. 解析整数
25 if(doc.HasMember("Int") && doc["Int"].IsInt())
26 {
27 cout << "Int = " << doc["Int"].GetInt() << endl;
28 }
29 //2. 解析浮点型
30 if(doc.HasMember("Double") && doc["Double"].IsDouble())
31 {
32 cout << "Double = " << doc["Double"].GetDouble() << endl;
33 }
34 //3. 解析字符串
35 if(doc.HasMember("String") && doc["String"].IsString())
36 {
37 cout << "String = " << doc["
String"].GetString() << endl;
38 }
39 //4. 解析结构体
40 if(doc.HasMember("Object") && doc["Object"].IsObject())
41 {
42 const rapidjson::Value& object = doc["Object"];
43 if(object.HasMember("name") && object["name"].IsString())
44 {
45 cout << "Object.name = " << object["name"].GetString() << endl;
46 }
47 if(object.HasMember("age") && object["age"].IsInt())
48 {
49 cout << "Object.age = " << object["age"].GetInt() << endl;
50 }
51 }
52 //5. 解析数组类型
53 //5.1 整型数组类型
54 if(doc.HasMember("IntArray") && doc["IntArray"].IsArray())
55 {
56 //5.1.1 将字段转换成为rapidjson::Value类型
57 const rapidjson::Value& array = doc["IntArray"];
58 //5.1.2 获取数组长度
59 size_t len = array.Size();
60 //5.1.3 根据下标遍历,注意将元素转换为相应类型,即需要调用GetInt()
61 for(size_t i = 0; i < len; i++)
62 {
63 cout << "IntArray[" << i << "] = " << array[i].GetInt() << endl;
64 }
65 }
66 //5.2 浮点型数组类型
67 if(doc.HasMember("DoubleArray") && doc["DoubleArray"].IsArray())
68 {
69 const rapidjson::Value& array = doc["DoubleArray"];
70 size_t len = array.Size();
71 for(size_t i = 0; i < len; i++)
72 {
73 //为防止类型不匹配,一般会添加类型校验
74 if(array[i].IsDouble())
75 {
76 cout << "DoubleArray[" << i << "] = " << array[i].GetDouble() << endl;
77 }
78 }
79 }
80 //5.3 字符串数组类型
81 if(doc.HasMember("StringArray") && doc["StringArray"].IsArray())
82 {
83 const rapidjson::Value& array = doc["StringArray"];
84 size_t len = array.Size();
85 for(size_t i = 0; i < len; i++)
86 {
87 //为防止类型不匹配,一般会添加类型校验
88 if(array[i].IsString())
89 {
90 cout << "StringArray[" << i << "] = " << array[i].GetString() << endl;
91 }
92 }
93 }
94 //5.4 混合型
95 if(doc.HasMember("MixedArray") && doc["MixedArray"].IsArray())
96 {
97 const rapidjson::Value& array = doc["MixedArray"];
98 size_t len = array.Size();
99 for(size_t i = 0; i < len; i++)
100 {
101 //为防止类型不匹配,一般会添加类型校验
102 if(array[i].IsString())
103 {
104 cout << "MixedArray[" << i << "] = " << array[i].GetString() << endl;
105 }
106 else if(array[i].IsBool())
107 {
108 cout << "MixedArray[" << i << "] = " << array[i].GetBool() << endl;
109 }
110 else if(array[i].IsInt())
111 {
112 cout << "MixedArray[" << i << "] = " << array[i].GetInt() << endl;
113 }
114 else if(array[i].IsDouble())
115 {
116 cout << "MixedArray[" << i << "] = " << array[i].GetDouble() << endl;
117 }
118 }
119 }
120 //5.5 结构体数组类型
121 if(doc.HasMember("People") && doc["People"].IsArray())
122 {
123 const rapidjson::Value& array = doc["People"];
124 size_t len = array.Size();
125 for(size_t i = 0; i < len; i++)
126 {
127 const rapidjson::Value& object = array[i];
128 //为防止类型不匹配,一般会添加类型校验
129 if(object.IsObject())
130 {
131 cout << "ObjectArray[" << i << "]: ";
132 if(object.HasMember("name") && object["name"].IsString())
133 {
134 cout << "name=" << object["name"].GetString();
135 }
136 if(object.HasMember("age") && object["age"].IsInt())
137 {
138 cout << ", age=" << object["age"].GetInt();
139 }
140 if(object.HasMember("sex") && object["sex"].IsBool())
141 {
142 cout << ", sex=" << (object["sex"].GetBool() ? "男" : "女") << endl;
143 }
144 }
145 }
146 }
147 }
148 /**
149 * 最后注意:因为rapidjson不会做安全校验,所以要自己做安全校验,以int整型为例
150 * “if(object.HasMember("age") && object["age"].IsInt()) {}”
151 * 这句校验很重要,既要校验有该子段,也要校验类型正确,否则会引发程序崩溃
152 */
153 }
所有的代码都放在上面了,我想不用解释太多,代码浅显易懂,不懂的话可以回复评论。