rapidjson庫的基本使用


轉自: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": [
        10, 
        20, 
        30
    ], 
    "DoubleArray": [
        1, 
        2, 
        3
    ], 
    "StringArray": [
        "one", 
        "two", 
        "three"
    ], 
    "MixedArray": [
        "one", 
        50, 
        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>
 5  
 6 using namespace std;
 7  
 8 void Serialize_1()
 9 {
10     rapidjson::StringBuffer strBuf;
11     rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
12  
13     writer.StartObject();
14  
15     //1. 整數類型
16     writer.Key("Int");
17     writer.Int(1);
18  
19     //2. 浮點類型
20     writer.Key("Double");
21     writer.Double(12.0000001);
22  
23     //3. 字符串類型
24     writer.Key("String");
25     writer.String("This is a string");
26  
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();
35  
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();
45  
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();
54  
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();
62  
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();
72  
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();
88  
89     writer.EndObject();
90  
91     string data = strBuf.GetString();
92     cout << data << endl;
93 }

2. 接下來這種方式是我剛開始學習使用該庫時網上收到的結果,使用不像上面那么方便

 1 #include "rapidjson/document.h"
 2 #include "rapidjson/stringbuffer.h"
 3 #include "rapidjson/writer.h"
 4  
 5  
 6 void Serialize_2()
 7 {
 8     rapidjson::Document doc;
 9     doc.SetObject();
10     rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
11  
12     //1. 整型類型
13     doc.AddMember("Int", 1, allocator);
14  
15     //2. 浮點類型
16     doc.AddMember("Double", 12.00001, allocator);
17  
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);
33  
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);
39  
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);
47  
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);
54  
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);
67  
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);
78  
79     rapidjson::StringBuffer strBuf;
80     rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
81     doc.Accept(writer);
82  
83     string data = strBuf.GetString();
84     cout << data << endl;
85 }

下面是解析的代碼,同樣的,采用的依舊上面那個json字符串,分門別類的已經整理好

  1 #include "rapidjson/document.h"
  2 #include "rapidjson/stringbuffer.h"
  3 #include "rapidjson/writer.h"
  4  
  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}]}";
 17  
 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 }

所有的代碼都放在上面了,我想不用解釋太多,代碼淺顯易懂,不懂的話可以回復評論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM