本示例操作演示:
1. Value的新建及key的访问,修改
2. 从字符串中解析json
3. 从文件中读取解析json
4.把json写入到文件
简介:
RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自 RapidXml。
- RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。
- RapidJSON 快。它的性能可与
strlen()
相比。可支持 SSE2/SSE4.2 加速。 - RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。
- RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
- RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及
"\u0000"
(空字符)
地址:
中文版官网:http://rapidjson.org/zh-cn/
rapidjson库下载网地址:https://github.com/miloyip/rapidjson
安装:
RapidJSON 是只有头文件的 C++ 库。只需把 include/rapidjson
目录复制至系统或项目的 include 目录中
结果如下图:
示例代码下载地址:
https://download.csdn.net/download/yzf279533105/11223905
代码如下:
// rapidjson/example/simpledom/simpledom.cpp`
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
using namespace rapidjson;
using namespace std;
int main()
{
cout<<"json Value的新建及key的访问"<<endl;
Document jsonDoc; //生成一个dom元素Document
Document::AllocatorType &allocator = jsonDoc.GetAllocator(); //获取分配器
jsonDoc.SetObject(); //将当前的Document设置为一个object,也就是说,整个Document是一个Object类型的dom元素
// 新建Value对象1(object类型)
Value value1(kObjectType);
value1.AddMember("name","语文",allocator); // string型(给字段赋值,key必须为string型下同)
value1.AddMember("score",80,allocator); // 整型
value1.AddMember("right",true,allocator); // 整型
value1.AddMember("percent",12.3456789123,allocator);// double型
// 此时访问key是可以的
if (value1.HasMember("name")) // 判断是否存在该key
{
if (value1["name"].IsString()) // 再判断类型是否正确
{
cout<<"value1:name:"<<value1["name"].GetString()<<endl;
}
cout<<"value1:score:"<<value1["score"].GetInt()<<endl; // 直接这样写有风险
}
// 新建Value对象(数组类型)
Value value2(kArrayType);
value2.PushBack(1,allocator);
value2.PushBack(2,allocator);
value2.PushBack(3,allocator);
cout<<"value:size()数组中元素个数:"<<value2.Size()<<endl;
// 合并一个整体
Value value3(kObjectType);
value3.AddMember("name","xiaoming",allocator);
value3.AddMember("age",18,allocator);
value3.AddMember("value1",value1,allocator); // 整个value1作为key的值
value3.AddMember("value2",value2,allocator); // 整个value2作为key的值
// 转为string
StringBuffer str;
Writer<StringBuffer> writer(str);
value3.Accept(writer);
string strJson = str.GetString();
cout<<"value3:"<<strJson.c_str()<<endl;
// key的访问
// 此时访问value1是不行的,why!!!难道就因为加入到了value3中?????,代码暂时注释掉
// if (value1.HasMember("name")) // 判断是否存在该key
// {
// if (value1["name"].IsString()) // 再判断类型是否正确
// {
// cout<<"value1:name:"<<value1["name"].GetString()<<endl;
// }
// cout<<"value1:age:"<<value1["age"].GetBool()<<endl; // 直接这样写有风险
// }
// 访问value3是可以的
if (value3.HasMember("age")) // 判断是否存在该key
{
if (value3["age"].IsInt()) // 整形,其实用IsUint(),IsInt64(),IsUint64()都是可以的
{
cout<<"value3:age:"<<value3["age"].GetInt()<<endl;
}
// 访问内部的value1中的变量
if (value3.HasMember("value1") && value3["value1"].IsObject())
{
Value tempV1;
tempV1 = value3["value1"]; // 注意:不能写成: Value tempV1 = value3["value1"]
if (tempV1.HasMember("percent") && tempV1["percent"].IsDouble())
{
cout<<"value3:value1:percent:"<<tempV1["percent"].GetDouble()<<endl;
}
}
// 访问内部value2
if (value3.HasMember("value2") && value3["value2"].IsArray())
{
Value tempV2;
tempV2 = value3["value2"]; // 注意:不能写成: Value tempV2 = value3["value2"]
for (int i=0;i<tempV2.Size();i++)
{
cout<<tempV2[i].GetInt()<<endl;
}
}
}
cout<<"\n从字符串中解析json"<<endl;
const char* jsonStr = "{\"open\":true,\"award\":300,\"cities\":[34,12,56],\"url\":\"www.baidu.com\"}";
Document docu;
docu.Parse(jsonStr);
if (docu.HasMember("open") && docu["open"].IsBool())
{
cout<<"从字符串中解析json,子段open:"<<docu["open"].GetBool()<<endl;
}
// 修改(true改为false)
docu["open"].SetBool(false);
// 其他字段解析,修改与上面的类似,不再重复
// 把DOM转换成Jons字符串
StringBuffer str2;
Writer<StringBuffer> writer2(str2);
docu.Accept(writer2);
cout<<str2.GetString()<<endl;
cout<<"\n从文件中读取json"<<endl;
// 办法1(代码简单,推荐)
Document docu2;
ifstream ifs("in.json");
IStreamWrapper isw(ifs);
docu2.ParseStream(isw);
// 办法2(虽然注释掉了,其实可以用的)
// FILE* myFile = fopen("in.json", "r"); //windows平台使用rb
// if (myFile != NULL)
// {
// char readBuff[65535];
// FileReadStream inputStream(myFile,readBuff,sizeof(readBuff)); //创建一个输入流
// docu2.ParseStream(inputStream); //将读取的内容转换为dom元素
// fclose(myFile); //关闭文件,很重要
// }
// //判断解析从流中读取的字符串是否有错误
// if (docu2.HasParseError()) {
// cout<<"读取json文件失败,err:"<<docu2.GetParseError()<<endl; //打印错误编号
// return 0;
// }
if (docu2.HasMember("award") && docu2["award"].IsInt())
{
cout<<"从文件中解析json,子段award:"<<docu2["award"].GetInt()<<endl;
}
// 修改(300改为500)
docu2["award"].SetInt(500);
// 写入到文件中
cout<<"\n开始写入json到文件"<<endl;
ofstream ofs("out.json");
OStreamWrapper osw(ofs);
Writer<OStreamWrapper> writer3(osw);
docu2.Accept(writer3);
cout<<"\n写入json到文件成功"<<endl;
return 0;
}