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. 下面这段代码是我最喜欢用的一种方式,使用字符串缓冲器生成
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include <iostream>
#include <string> using namespace std; void Serialize_1()
{
rapidjson::StringBuffer strBuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf); writer.StartObject(); //1. 整数类型
writer.Key("Int");
writer.Int(); //2. 浮点类型
writer.Key("Double");
writer.Double(12.0000001); //3. 字符串类型
writer.Key("String");
writer.String("This is a string"); //4. 结构体类型
writer.Key("Object");
writer.StartObject();
writer.Key("name");
writer.String("qq849635649");
writer.Key("age");
writer.Int();
writer.EndObject(); //5. 数组类型
//5.1 整型数组
writer.Key("IntArray");
writer.StartArray();
//顺序写入即可
writer.Int();
writer.Int();
writer.Int();
writer.EndArray(); //5.2 浮点型数组
writer.Key("DoubleArray");
writer.StartArray();
for(int i = ; i < ; i++)
{
writer.Double(i * 1.0);
}
writer.EndArray(); //5.3 字符串数组
writer.Key("StringArray");
writer.StartArray();
writer.String("one");
writer.String("two");
writer.String("three");
writer.EndArray(); //5.4 混合型数组
//这说明了,一个json数组内容是不限制类型的
writer.Key("MixedArray");
writer.StartArray();
writer.String("one");
writer.Int();
writer.Bool(false);
writer.Double(12.005);
writer.EndArray(); //5.5 结构体数组
writer.Key("People");
writer.StartArray();
for(int i = ; i < ; i++)
{
writer.StartObject();
writer.Key("name");
writer.String("qq849635649");
writer.Key("age");
writer.Int(i * );
writer.Key("sex");
writer.Bool((i % ) == );
writer.EndObject();
}
writer.EndArray(); writer.EndObject(); string data = strBuf.GetString();
cout << data << endl;
}
2. 接下来这种方式是我刚开始学习使用该库时网上收到的结果,使用不像上面那么方便
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h" void Serialize_2()
{
rapidjson::Document doc;
doc.SetObject();
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); //1. 整型类型
doc.AddMember("Int", , allocator); //2. 浮点类型
doc.AddMember("Double", 12.00001, allocator); //3. 字符串类型
//正确方式
string str= "This is a string";
rapidjson::Value str_value(rapidjson::kStringType);
str_value.SetString(str.c_str(), str.size());
if(!str_value.IsNull())
{
doc.AddMember("String", str_value, allocator);
}
/**
* 注:以下方式不正确,可能成功,也可能失败,因为字符串写入json要重新开辟内存,
* 如果使用该方式的话,当数据是字符串常量的话是没问题的,如果为变量就会显示乱码,所
* 以为保险起见,我们显式的分配内存(无需释放)
*/
//doc.AddMember("String", str.data(), allocator); //4. 结构体类型
rapidjson::Value object(rapidjson::kObjectType);
object.AddMember("name", "qq849635649", allocator); //注:常量是没有问题的
object.AddMember("age", , allocator);
doc.AddMember("Object", object, allocator); //5. 数组类型
//5.1 整型数组
rapidjson::Value IntArray(rapidjson::kArrayType);
IntArray.PushBack(, allocator);
IntArray.PushBack(, allocator);
IntArray.PushBack(, allocator);
doc.AddMember("IntArray", IntArray, allocator); //5.2 浮点型数组
rapidjson::Value DoubleArray(rapidjson::kArrayType);
DoubleArray.PushBack(1.0, allocator);
DoubleArray.PushBack(2.0, allocator);
DoubleArray.PushBack(3.0, allocator);
doc.AddMember("DoubleArray", DoubleArray, allocator); //5.3 字符型数组
rapidjson::Value StringArray(rapidjson::kArrayType);
string strValue1 = "one";
string strValue2 = "two";
string strValue3 = "three";
str_value.SetString(strValue1.c_str(), strValue1.size());
StringArray.PushBack(str_value, allocator);
str_value.SetString(strValue2.c_str(), strValue2.size());
StringArray.PushBack(str_value, allocator);
str_value.SetString(strValue3.c_str(), strValue3.size());
StringArray.PushBack(str_value, allocator);
doc.AddMember("StringArray", StringArray, allocator); //5.4 结构体数组
rapidjson::Value ObjectArray(rapidjson::kArrayType);
for(int i = ; i < ; i++)
{
rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("name", "qq849635649", allocator);//注:常量是没有问题的
obj.AddMember("age", i * , allocator);
ObjectArray.PushBack(obj, allocator);
}
doc.AddMember("ObjectArray", ObjectArray, allocator); rapidjson::StringBuffer strBuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
doc.Accept(writer); string data = strBuf.GetString();
cout << data << endl;
}
下面是解析的代码,同样的,采用的依旧上面那个json字符串,分门别类的已经整理好
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h" string data =
"{\"Int\":1,"
"\"Double\":12.0000001,"
"\"String\":\"This is a string\","
"\"Object\":{\"name\":\"qq849635649\",\"age\":25},"
"\"IntArray\":[10,20,30],"
"\"DoubleArray\":[1.0,2.0,3.0],"
"\"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}]}"; void parse() {
//创建解析对象
rapidjson::Document doc;
//首先进行解析,没有解析错误才能进行具体字段的解析
if(!doc.Parse(data.data()).HasParseError())
{
//1. 解析整数
if(doc.HasMember("Int") && doc["Int"].IsInt())
{
cout << "Int = " << doc["Int"].GetInt() << endl;
}
//2. 解析浮点型
if(doc.HasMember("Double") && doc["Double"].IsDouble())
{
cout << "Double = " << doc["Double"].GetDouble() << endl;
}
//3. 解析字符串
if(doc.HasMember("String") && doc["String"].IsString())
{
cout << "String = " << doc["String"].GetString() << endl;
}
//4. 解析结构体
if(doc.HasMember("Object") && doc["Object"].IsObject())
{
const rapidjson::Value& object = doc["Object"];
if(object.HasMember("name") && object["name"].IsString())
{
cout << "Object.name = " << object["name"].GetString() << endl;
}
if(object.HasMember("age") && object["age"].IsInt())
{
cout << "Object.age = " << object["age"].GetInt() << endl;
}
}
//5. 解析数组类型
//5.1 整型数组类型
if(doc.HasMember("IntArray") && doc["IntArray"].IsArray())
{
//5.1.1 将字段转换成为rapidjson::Value类型
const rapidjson::Value& array = doc["IntArray"];
//5.1.2 获取数组长度
size_t len = array.Size();
//5.1.3 根据下标遍历,注意将元素转换为相应类型,即需要调用GetInt()
for(size_t i = ; i < len; i++)
{
cout << "IntArray[" << i << "] = " << array[i].GetInt() << endl;
}
}
//5.2 浮点型数组类型
if(doc.HasMember("DoubleArray") && doc["DoubleArray"].IsArray())
{
const rapidjson::Value& array = doc["DoubleArray"];
size_t len = array.Size();
for(size_t i = ; i < len; i++)
{
//为防止类型不匹配,一般会添加类型校验
if(array[i].IsDouble())
{
cout << "DoubleArray[" << i << "] = " << array[i].GetDouble() << endl;
}
}
}
//5.3 字符串数组类型
if(doc.HasMember("StringArray") && doc["StringArray"].IsArray())
{
const rapidjson::Value& array = doc["StringArray"];
size_t len = array.Size();
for(size_t i = ; i < len; i++)
{
//为防止类型不匹配,一般会添加类型校验
if(array[i].IsString())
{
cout << "StringArray[" << i << "] = " << array[i].GetString() << endl;
}
}
}
//5.4 混合型
if(doc.HasMember("MixedArray") && doc["MixedArray"].IsArray())
{
const rapidjson::Value& array = doc["MixedArray"];
size_t len = array.Size();
for(size_t i = ; i < len; i++)
{
//为防止类型不匹配,一般会添加类型校验
if(array[i].IsString())
{
cout << "MixedArray[" << i << "] = " << array[i].GetString() << endl;
}
else if(array[i].IsBool())
{
cout << "MixedArray[" << i << "] = " << array[i].GetBool() << endl;
}
else if(array[i].IsInt())
{
cout << "MixedArray[" << i << "] = " << array[i].GetInt() << endl;
}
else if(array[i].IsDouble())
{
cout << "MixedArray[" << i << "] = " << array[i].GetDouble() << endl;
}
}
}
//5.5 结构体数组类型
if(doc.HasMember("People") && doc["People"].IsArray())
{
const rapidjson::Value& array = doc["People"];
size_t len = array.Size();
for(size_t i = ; i < len; i++)
{
const rapidjson::Value& object = array[i];
//为防止类型不匹配,一般会添加类型校验
if(object.IsObject())
{
cout << "ObjectArray[" << i << "]: ";
if(object.HasMember("name") && object["name"].IsString())
{
cout << "name=" << object["name"].GetString();
}
if(object.HasMember("age") && object["age"].IsInt())
{
cout << ", age=" << object["age"].GetInt();
}
if(object.HasMember("sex") && object["sex"].IsBool())
{
cout << ", sex=" << (object["sex"].GetBool() ? "男" : "女") << endl;
}
}
}
}
}
/**
* 最后注意:因为rapidjson不会做安全校验,所以要自己做安全校验,以int整型为例
* “if(object.HasMember("age") && object["age"].IsInt()) {}”
* 这句校验很重要,既要校验有该子段,也要校验类型正确,否则会引发程序崩溃
*/
}
所有的代码都放在上面了,我想不用解释太多,代码浅显易懂,不懂的话可以回复评论。
rapidjson库的基本使用的更多相关文章
- 基于RapidJSON的操作库
需要安装配置RapidJSON库 /******************************************************************* * summery: 提供便 ...
- Cocos2d-x移植到WindowsPhone8移植问题-libcurl库移植问题
在Cocos2d-x 3.x最新版本中提供了Windows Phone 8平台移植libcurl库所需要的头文件和库文件.但要在Windows Phone 8平台成功移植libcurl库还是很不容易, ...
- cocos2d-x3.x使用rapidjson
rapidjson效率高,所以之前cocostudio里面解析用的jsoncpp也换成了rapidjson. 引擎又带有rapidjson库,所以不用单独去下载,直接就可以用. 这里主要写一下关于解析 ...
- Cocos2d-x 3.0 Json用法 Cocos2d-x xml解析
Cocos2d-x 3.0 加入了rapidjson库用于json解析.位于external/json下. rapidjson 项目地址:http://code.google.com/p/rapidj ...
- cocos2d_x_06_游戏_一个都不能死
终于效果图: 环境版本号:cocos2d-x-3.3beta0 使用内置的物理引擎 游戏主场景 // // HeroScene.h // 01_cocos2d-x // // Created by b ...
- (27)Cocos2d-x 3.0 Json用法
Cocos2d-x 3.0 加入了rapidjson库用于json解析.位于external/json下. rapidjson 项目地址:http://code.google.com/p/rapidj ...
- C++ JSON解析库RapidJSON
https://github.com/Tencent/rapidjson jsontext.txt { "result" : [ { "face_id" : & ...
- 值得推荐的C/C++框架和库
值得推荐的C/C++框架和库 [本文系外部转贴,原文地址:http://coolshell.info/c/c++/2014/12/13/c-open-project.htm]留作存档 下次造轮子前先看 ...
- [转载]C/C++框架和库
C/C++框架和库 装载自:http://blog.csdn.net/xiaoxiaoyeyaya/article/details/42541419 值得学习的C语言开源项目 Webbench Web ...
随机推荐
- php版本CKEditor 4和CKFinder安装及配置
下载并解压CKEditor 4和CKFinder CKEditor 4下载地址:https://ckeditor.com/cke4/builder,选择自定义的版本,记得加上中文语言包 CKFinde ...
- mysql分页查询优化(索引延迟关联)
对于web后台报表导出是一种常见的功能点,实际对应服务后端即数据库的排序分页查询.如下示例为公司商户积分报表导出其中一个sql ,当大批量的导出请求进入时候,mysql的cpu急剧上升瞬间有拖垮库的风 ...
- Linux学习笔记03—初识Linux
命令介绍 忘记root密码的处理方法 系统安装盘的救援模式的使用 一.命令介绍 1.LS命令 ls 查看当前目录下的文件 Ls –l 等同于ll 查看目录的详细信息 Ls –a 查看当前目录下的所有文 ...
- ARM 汇编与C调用的若干问题(一般函数调用情况)
ARM 汇编与C之间的函数调用需要符合ATPCS,建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递:若形参个数大于4,大于4的部分必须通过堆栈进行传 ...
- CF 222 (DIV 1)
A: 我是bfs出一颗树,然后删掉树后面的k个结点. 其实也可以直接bfs出一块连通的s - k个点,其余的.打X就可以了. 很水的题目. /* *************************** ...
- jquery-chosen设置默认值
<span style="font-size:18px;"> <select id="select1" class="select1 ...
- 关于C++类型检查的一点小挫折
问题: 定义了一个float型数组Lut[],我让一个整型指针指向数组名int * Address=lut ; VS2008报错: error C2440: '=' : cannot conv ...
- 改变窗体大小视图区图形也会跟着变化 MFC
怎样实现窗体缩放,视图区里的图形也会跟着变化 在CMFCView类中加入三个消息函数: 在类向导中选中CMFCView类,点击右键---->类向导------>消息--------> ...
- 关于在Struts2的Action中使用domain模型接收参数的问题
最近在搭建一个最新的ssh2框架,今天在调试的时候,发现了一个以前一直没有注意过的问题,我在Action中使用域模型的方式去接收jsp画面中的参数的时候,发现参数总是接收不完,头一次遇到这种问题,现在 ...
- 【python】python安装步骤
1.官网下载python 官网地址:https://www.python.org/getit/ 2.下载完成后点击安装 勾选Add python to PATH 是可以自己去配置环境变量的 注意:这里 ...