C/C++C++Json解析和生成的开源库:RapidJson和JsonCpp
Posted 拉伊卜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++C++Json解析和生成的开源库:RapidJson和JsonCpp相关的知识,希望对你有一定的参考价值。
目录
一,RapidJson和JsonCpp对比
RapidJson和JsonCpp都是C++中流行的JSON解析器和生成器,并且都是开源库,具有许多相似的功能,但也有不同之处。
1.RapidJson优势
- RapidJSON的速度比JsonCpp更快,因为它使用了更高效的内存管理和解析算法。
- RapidJSON在内存使用方面比JsonCpp更加高效,因为它使用了基于堆栈的内存池。
- RapidJSON提供了很多灵活的解析和生成JSON的选项,例如支持按需解析和生成,可以通过模板自定义数据类型的序列化和反序列化等等。
- RapidJSON代码体积非常小,只有几个头文件和源文件,没有外部依赖,而且只依赖于标准C++库,因此很容易部署到现有项目中,非常轻量级。
2.JsonCpp优势
- JsonCpp是一个稳定且经过长期使用和测试的库,具有更广泛的社区支持和使用。
- JsonCpp提供了更加简单的API,易于学习和使用,它的代码结构也很清晰,方便阅读和理解。
- JsonCpp提供了更多的功能,例如支持JSON格式化,可以在解析时检查语法错误等等。
- JsonCpp可移植性好,可以在多种操作系统和编译器上运行,包括Windows、Linux和Mac OS X。
3.两者的差异
- RapidJSON的设计理念更加注重性能,而JsonCpp的设计理念更加注重易用性。
- RapidJSON提供了更多的可扩展性选项,而JsonCpp则更加易于移植。
4.根据具体需求进行选择
- 如果你需要一个快速和高效处理大量JSON数据的库,并且愿意使用更灵活的解析和生成选项,那么RapidJSON是一个很好的选择。
- 如果你需要一个更稳定,易于使用和可移植的库,并且需要额外的功能(例如JSON格式化),那么JsonCpp是一个不错的选择。
二,RapidJson和JsonCpp下载地址
1.RapidJson下载
2.JsonCpp下载
三,RapidJson头文件及其功能介绍
1.rapidjson/document.h
该头文件包含了DOM解析器和生成器所需的类和函数。DOM解析器是一种将JSON文本解析为DOM树的解析器,DOM树的结构对应于JSON文本的语法结构。DOM生成器是一种将DOM树转换为JSON文本的生成器。该头文件中的类包括:
- GenericValue: 一个通用的JSON值类型,可以表示任何类型的JSON值,包括null、bool、int、double、字符串、数组和对象。
- Document: 表示一个JSON文档,包含一个根节点和相关的配置选项。
2.rapidjson/writer.h
该头文件包含了生成器所需的类和函数,用于将DOM树转换为JSON文本。该头文件中的类包括:
- Writer: 将DOM树转换为JSON文本的基类。
- PrettyWriter: 继承自Writer,支持格式化输出的生成器,生成的JSON文本带有缩进和换行符。
- WriterTraits: 定义了生成器的一些常见特性,如逗号的位置、缩进符号等。
3.rapidjson/stringbuffer.h
该头文件包含了一个字符串缓冲区类,用于存储生成器生成的JSON文本。该头文件中的类包括:
- StringBuffer: 表示一个字符串缓冲区,提供了向缓冲区写入数据的方法。
- CrtAllocator: 表示一个内存分配器,用于分配和释放内存。
4.rapidjson/reader.h
该头文件包含了SAX解析器所需的类和函数,用于将JSON文本解析为SAX事件流。SAX解析器是一种将JSON文本解析为SAX事件流的解析器,SAX事件流表示JSON文本的语法结构。该头文件中的类包括:
- BaseReaderHandler: 解析器事件处理程序的基类。
- Reader: 将JSON文本解析为SAX事件流的解析器。
5.rapidjson/error/en.h
该头文件包含了RapidJSON的错误码和错误信息的定义。该头文件中的类包括:
- ParseErrorCode: 定义了解析器可能出现的错误码。
- GetParseErrorFunc: 用于获取错误码对应的错误信息。
6.rapidjson/error/error.h
该头文件包含了解析器和生成器可能出现的错误异常类的定义。该头文件中的类包括:
- ParseException: 解析器可能抛出的异常类。
- RuntimeError: 生成器可能抛出的异常类。
四,RapidJson使用案例
1.安装RapidJson
1.RapidJSON 是只有头文件的 C++ 库,没有安装过程。下载解压后只需把 include/rapidjson
目录拷贝到你的项目中即可开始使用(支持SAX和DOM两种解析方式:SAX解析器将JSON流解析为事件序列,而DOM解析器将JSON解析为内存中的树形结构)
VS2019工程
VsCode工程(参考)
2.测试的Json数据
准备测试读写的 example.json 文件内容(文件路径 E:\\example.json)
"FirstName": "Fu",
"LastName": "Cong",
"Age": 24,
"Address":
"Street": "首创悦榕汇",
"City": "BeiJing",
"Country": "BeiJing"
,
"Phone numbers": [
"+44 12345",
678910
]
3.使用DOM解析器解析JSON
#include <iostream>
#include <fstream>
#include "rapidjson/document.h"
//返回指定文件的所有内容
char* readFile(std::string path)
std::ifstream ifs;
ifs.open(path, ios::in);
char* data = NULL;
long length; //文件大小
if (ifs.is_open())
//文件打开成功
ifs.seekg(0, ios::end); //将文件流光标移动到文件末尾
length = ifs.tellg(); //获取文件内容的大小(相对于文件开头的位移量来表示)
data = (char*)malloc((length + 1) * sizeof(char));
memset(data, '\\0', length);
ifs.seekg(0, ios::beg); //将文件光标重置到文件开头位置
ifs.read(data, length); //一次性读取所有字符串
ifs.close(); //关闭文件流
return data;
return NULL;
void readJson()
std::string jsonData(readFile("E:\\\\example.json"));
rapidjson::Document doc; //Document是一个表示根DOM的JSON值。根可以是对象或数组。
if(doc.Parse(jsonData.c_str()).HasParseError())
std::cout << "“正常”解析,解码字符串到新的缓冲区失败!" << std::endl;
return;
else
std::cout << "解析文档成功!" << std::endl;
if (doc.IsObject())
//JSON根数据是对象
if (doc.HasMember("FirstName") && doc["FirstName"].IsString())
std::cout << "FirstName:" << doc["FirstName"].GetString() << std::endl;
if(doc.HasMember("LastName") && doc["LastName"].IsString())
std::cout << "LastName:" << doc["LastName"].GetString() << std::endl;
if(doc.HasMember("Age") && doc["Age"].IsInt())
std::cout << "Age:" << doc["Age"].GetInt() << std::endl;
if(doc.HasMember("Address") && doc["Address"].IsObject())
rapidjson::Value &subObj = doc["Address"].GetObject();
if(subObj.HasMember("Street") && subObj["Street"].IsString())
std::cout << "Street:" << subObj["Street"].GetString() << std::endl;
if(subObj.HasMember("City") && subObj["City"].IsString())
std::cout << "City:" << subObj["City"].GetString() << std::endl;
//从0.2版本开始,可以使用单一查找来检查成员的存在及其值(个人觉得并不好用)
rapidjson::Value::MemberIterator street = subObj.FindMember("Country");
if(street != doc.MemberEnd() && street->value.IsString())
std::cout << "Country:" << street->value.GetString() << std::endl;
if(doc.HasMember("Phone numbers") && doc["Phone numbers"].IsArray())
const rapidjson::Value& arr = doc["Phone numbers"];
for(rapidjson::SizeType i = 0; i< arr.Size();i++)
if (arr[i].IsString())
std::cout << arr[i].GetString() << std::endl;
if (arr[i].IsInt())
std::cout << arr[i].GetInt() << std::endl;
else if(doc.IsArray())
//JSON根数据是数组
4.使用DOM解析器生成JSON
#include <iostream>
#include <fstream>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h" //存储生成的JSON文本,然后可以轻松地将其输出到文件或其他输出流中
#include "rapidjson/prettywriter.h" //生成带有格式的JSON文本,并将其输出到文件中
void writeJson()
rapidjson::Document docRoot;
docRoot.SetObject(); //创建一个JSON对象
//加入键值对
docRoot.AddMember("FirstName","Fu",docRoot.GetAllocator());
docRoot.AddMember("LastName","Cong",docRoot.GetAllocator());
docRoot.AddMember("Age",24,docRoot.GetAllocator());
//添加子对象
rapidjson::Value subObj(rapidjson::kObjectType);
subObj.AddMember("Street","首创悦榕汇",docRoot.GetAllocator());
subObj.AddMember("City","BeiJing",docRoot.GetAllocator());
subObj.AddMember("Country","BeiJing",docRoot.GetAllocator());
docRoot.AddMember("Age",subObj,docRoot.GetAllocator());
//添加数组
rapidjson::Value PhoneNumber(rapidjson::kArrayType);
rapidjson::Value val1;
val1.SetString("+44 12345", docRoot.GetAllocator());
PhoneNumber.PushBack(val1,docRoot.GetAllocator());
rapidjson::Value val2;
val2.SetInt(678910);
PhoneNumber.PushBack(val2,docRoot.GetAllocator());
docRoot.AddMember("Phone numbers",PhoneNumber,docRoot.GetAllocator());
//输出到Json文件中
rapidjson::StringBuffer buffer; //创建一个StringBuffer对象
// rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); //创建一个Writer对象并将其与StringBuffer对象连接起来,生成不带有格式的JSON文本
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer); //创建一个PrettyWriter对象并将其与StringBuffer对象连接起来,生成带有格式的JSON文本
docRoot.Accept(writer); //将JSON对象写入StringBuffer对象
std::string json_str = buffer.GetString(); //将StringBuffer对象转换为std::string
std::ofstream ofs;
ofs.open("E:\\\\example.json",std::ios::out);
if(ofs.is_open())
ofs << json_str;
ofs.close();
五,JsonCpp使用
参考这篇文章: JsonCpp编译和使用 | 爱编程的大丙
六,其它
cJSON的使用 :cJSON的API介绍和使用
以上是关于C/C++C++Json解析和生成的开源库:RapidJson和JsonCpp的主要内容,如果未能解决你的问题,请参考以下文章