• 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 }

    所有的代码都放在上面了,我想不用解释太多,代码浅显易懂,不懂的话可以回复评论。

  • 相关阅读:
    入职演讲
    关于EOM(Enterprise Operating Model)企业经营模型
    程序员都很自信
    全能型的程序员
    用EOM的眼光评判‘我要做全国最最好的标准权限组件和通用权限管理软件’1
    用EOM的眼光评判‘我要做全国最最好的标准权限组件和通用权限管理软件’2
    用EOM的眼光评判‘我要做全国最最好的标准权限组件和通用权限管理软件’3
    用EOM的眼光评判‘我要做全国最最好的标准权限组件和通用权限管理软件’4
    “IT农民工”这一说法
    怎样快速确定程序员编程的水平
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/10334988.html
Copyright © 2020-2023  润新知