前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用rapidJson C++库生成JSON字符串

使用rapidJson C++库生成JSON字符串

作者头像
ccf19881030
发布于 2020-03-04 11:04:04
发布于 2020-03-04 11:04:04
7K00
代码可运行
举报
文章被收录于专栏:ccf19881030的博客ccf19881030的博客
运行总次数:0
代码可运行

前言

RapidJSON 是一个 C++ 的 JSON 解析器及生成器,它是腾讯公司开发的一款高效的 C++ JSON 解析/生成器,提供 SAX 及 DOM 风格 API,中文官网地址为:http://rapidjson.org/zh-cn/,从这里可以看到它的详细说明文档;对应的Github地址为:https://github.com/Tencent/rapidjson,从rapidjson-github上面获取它的最新的源代码,然后把include目录下的rapidjson目录放在自己指定项目下或者自己项目工程对应的include等目录下,使用时包含rapid目录下对应的头文件就可以了,无需编译成静态库文件。它的灵感来自 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”(空字符)。

可以在Linux发行版CentOS7下使用git clone https://github.com/Tencent/rapidjson命令从github上面下载对应的rapidjson的最新代码,以下是我在我的腾讯云主机上下载rapidjson的代码,以及rapidjson项目的目录结构,如下图所示:

从上图rapidjson项目的目录中可以看出,include文件包含的rapidjson文件就是我们使用rapidjson进行json字符串操作时所需要引入的头文件,example是一些代码示例,可供参考。

运行官方的simpledom.cpp示例程序

// simpledom.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// JSON simple example
// This example does not handle errors.

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>

using namespace rapidjson;

int main() {
    // 1. Parse a JSON string into DOM.
    const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
    Document d;
    d.Parse(json);

    // 2. Modify it by DOM.
    Value& s = d["stars"];
    s.SetInt(s.GetInt() + 1);

    // 3. Stringify the DOM
    StringBuffer buffer;
    Writer<StringBuffer> writer(buffer);
    d.Accept(writer);

    // Output {"project":"rapidjson","stars":11}
    std::cout << buffer.GetString() << std::endl;
    return 0;
}

在我的腾讯云CentOs7.5主机上的运行截图如下:

应用场景

之前使用过rapidjson读取过激光雷达的数据,最近在实际C++项目开发过程中需要将从设备客户端发送的HJ212报警数据解析后生成指定的JSON格式,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
   "Stcode": "SS1311054",
   "Timestamp": "2020-02-26 13:50:41",
   "Alarm": [{
   	"paramCode": "EP111",
   	"value": 1.0,
   	"mark": "N"
   }, {
   	"paramCode": "EP113",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "EP112",
   	"value": 1.0,
   	"mark": "N"
   }, {
   	"paramCode": "EP110",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "",
   	"value": 0.0,
   	"mark": "N"
   }, {
   	"paramCode": "EP120",
   	"value": 21.2,
   	"mark": "N"
   }, {
   	"paramCode": "EP121",
   	"value": 46.2,
   	"mark": "N"
   }, {
   	"paramCode": "EP122",
   	"value": 26.5,
   	"mark": "N"
   }, {
   	"paramCode": "EP123",
   	"value": 41.6,
   	"mark": "N"
   }, {
   	"paramCode": "EP124",
   	"value": 2.297,
   	"mark": "N"
   }, {
   	"paramCode": "EP125",
   	"value": 3.6,
   	"mark": "N"
   }, {
   	"paramCode": "EP126",
   	"value": 4.313,
   	"mark": "N"
   }, {
   	"paramCode": "EP114",
   	"value": 236.18,
   	"mark": "N"
   }, {
   	"paramCode": "EP115",
   	"value": 238.15,
   	"mark": "N"
   }, {
   	"paramCode": "EP116",
   	"value": 236.2,
   	"mark": "N"
   }, {
   	"paramCode": "EP118",
   	"value": 0.52,
   	"mark": "N"
   }]
}

上面的json字符串格式其实蛮简单的,Stcode表示站点编码,Timestamp表示数据时间,Alarm元素是一个数组,其中paramCode表示报警监测因子编码,value表示报警值,mark表示标记位,N表示正常,B表示异常。

使用rapidjson生成json字符串的两种方式

通常rapidjson生成json有两种方式,如下:

方式1: 使用rapidjson::Document和rapidjson::Document::AllocatorType分配器

使用rapidjson生成上面类似的C++代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

#include <iostream>


void test2()
{
	rapidjson::Document document;
	document.SetObject();
	rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
	rapidjson::Value object1(rapidjson::kObjectType);

	document.AddMember("StCode", "SS1211054", allocator);
	document.AddMember("Timestamp", "2020-02-24 13:50:41", allocator);

	// 数组
	rapidjson::Value alarmArray(rapidjson::kArrayType);

	for (int i = 0 ; i < 10; i++)
	{
		char strParamCode[128] = { 0 };
		sprintf(strParamCode, "param%d", i + 1);

		rapidjson::Value objectTemp(rapidjson::kObjectType);
		rapidjson::Value valueParamCode(strParamCode, document.GetAllocator());
		objectTemp.AddMember("paramCode", valueParamCode, allocator);
		objectTemp.AddMember("value", i + 10, allocator);
		objectTemp.AddMember("mark", "N", allocator);

		alarmArray.PushBack(objectTemp, allocator);
	}

	document.AddMember("Alarm", alarmArray, allocator);

	StringBuffer buffer;
	rapidjson::Writer<StringBuffer> writer(buffer);
	document.Accept(writer);

	std::string jsonStr2 = buffer.GetString();
	// 打印生成的json字符串
	std::cout << "test2(), strJson2为: " << jsonStr2.c_str() << std::endl;
}

int main(int argc, char* argv[])
{
	test2();
	
	return 0;
}

在VS2017中的程序运行截图如下:

方式2:使用rapidjson::Writer写入json

使用rapidjson生成上面类似的C++代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

#include <iostream>


void test3()
{
	rapidjson::StringBuffer s;
	rapidjson::Writer<rapidjson::StringBuffer> writer(s);

	writer.StartObject();
	// Stcode部分
	writer.Key("Stcode");

	writer.String("SS1211054");

	// 构造Timestamp
	writer.Key("Timestamp");

	writer.String("2020-02-27 23:50:41");

	writer.Key("Alarm");

	writer.StartArray();
	// 报警监测数据数组列表
	for (int i = 0; i < 5; i++)
	{
		char strParamCode[128] = { 0 };
		sprintf(strParamCode, "param%d", i);

		writer.StartObject();

		writer.Key("paramCode");

		writer.String(strParamCode);

		writer.Key("value");
		writer.Double(i*10 + 3.14);

		writer.Key("mark");

		writer.String("N");

		writer.EndObject();
	}
	writer.EndArray();

	writer.EndObject();

	std::string strJson3 = s.GetString();
	// 打印生成的json字符串
	std::cout << "test3(), strJson3为: " << strJson3.c_str() << std::endl;
}

int main(int argc, char* argv[])
{
	test2();
	
	return 0;
}

在VS2017中的程序运行截图如下:

从使用上来说,个人觉得第二种方式:使用rapidjson::Writer写入json更加方便。

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/02/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++的RapidJSON库的分析和实践
RapidJSON是一个用于解析和生成JSON数据的快速高效的C++库。它提供了简洁的API和卓越的性能,使得处理JSON数据在C++项目中变得更加简单和高效。本文将介绍RapidJSON库的一些关键特性,并探讨它在性能优化方面所做的实践。
大盘鸡拌面
2024/01/20
1.1K0
C++ RapidJson常用用法示例
C++对Json字符串和对象的转换使用没有直接的库,所以RapidJson就成了最常用的解析库,教程有大量详尽的用法示例,这里仅筛选出最常用的用法做完整示例,包括:
Cloudox
2021/11/23
2.7K0
【C++】开源:rapidjson数据解析库配置与使用
项目Github地址:https://github.com/Tencent/rapidjson
DevFrank
2024/07/24
5890
C++ 使用 rapidjson 生成 json 并解析
概述 使用 rapidjson 生成 json 并对其进行解析。 常用函数 AddMember 功能:往对象中添加一个键值对。GenericValue& rapidjson::GenericValue< Encoding, Allocator >::AddMember( GenericValue< Encoding, Allocator > & name, GenericValue< Encoding, Allocator > & value, Allocator & allo
云胡
2019/11/06
4.4K0
rapidjson常见使用示例
Document d; v2.CopyFrom(d, a); // 把整个document复制至v2,d不变 rapidjson为了最大化性能,大量使用了浅拷贝,使用之前一定要了解清楚。 如果采用了浅拷贝,特别要注意局部对象的使用,以防止对象已被析构了,却还在被使用。 // 需要#include的头文件: #include #include // en为english的简写,定义了取出错信息的函数GetParseError_En(errcode) #include #include // 示例1:解析一个字符串 // 运行输出结果: // count=2 // name=zhangsan // name=wangwu void x1() {     rapidjson::Document document; // 定义一个Document对象     std::string str = "{\"count\":2,\"names\":[\"zhangsan\",\"wangwu\"]}";     document.Parse(str.c_str()); // 解析,Parse()无返回值,也不会抛异常     if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功     {         // 可通过GetParseError()取得出错代码,         // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值         // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明,这里的En为English简写         // 函数GetErrorOffset()返回出错发生的位置         printf("parse error: (%d:%d)%s\n", document.GetParseError(), document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError()));     }     else     {         // 判断某成员是否存在         if (!document.HasMember("count") || !document.HasMember("names"))         {             printf("invalid format: %s\n", str.c_str());         }         else         {             // 如果count不存在,则运行程序会挂,DEBUG模式下直接abort             rapidjson::Value& count_json = document["count"];             // 如果count不是整数类型,调用也会挂,DEBUG模式下直接abort             // GetInt()返回类型为int             // GetUint()返回类型为unsigned int             // GetInt64()返回类型为int64_t             // GetUint64()返回类型为uint64_t             // GetDouble()返回类型为double             // GetString()返回类型为char*             // GetBool()返回类型为bool             int count = count_json.GetInt();             printf("count=%d\n", count);             // 方法GetType()返回枚举值: kNullType,kFalseType,kTrueType,kObjectType,kArrayType,kStringType,kNumberType             // 可用IsArray()判断是否为数组,示例: { "a": [1, 2, 3, 4] }             // 用IsString()判断是否为字符串值             // 用IsDouble()判断是否为double类型的值,示例: { "pi": 3.1416 }             // 用IsInt()判
一见
2018/08/06
13.1K1
hiredis和rapidjson库的使用小结
Hiredis 是Redis官方发布的C版本客户端 hiredis库。redis的源码中也有使用hiredis。比如redis-cli和Redis中的哨兵机制和主从机制,集群等都使用了hiredis。
杨永贞
2022/05/07
1.2K0
hiredis和rapidjson库的使用小结
rapidJson 的使用
头文件 #include "json/document.h" #include "json/prettywriter.h" #include "json/stringbuffer.h" 这是生成数组的 void test() { string info = "{\"id\":\"1111111\",\"cards\":[0,1,2,3,4,5,6,7,8,9],\"jiaoDiZhu\":\"\"}"; rapidjson::Document doc; doc.Parse<0>(
bear_fish
2018/09/20
3.1K0
C++中消息自动派发之三 About JSON Encode
  《C++ 消息自动派发》系列上篇介绍了IDL解析器,生成的C++代码只支持JSON转C++ struct。 经过新的重构,这次增加了对C++ struct 转JSON的支持。IDL解析器自动为C++ struct生成两个方法。   decode:实现json 转C++ struct 转。   encode:实现C++ struct 转json字符串。   现实应用中,网络服务器程序处理流程如下:   1> 网络层异步接收Client消息(本文讨论的应用都是基于json协议)   2> 对消息进行解析,如
知然
2018/03/09
1.5K0
VS Code编译file not found问题
最近在使用visual studio code的时候,编写c++代码,往往需要引入第三方的头文件,如下所示:
skyyws
2022/05/20
1K0
RapidJson的设计实现解读
DOM对象是不是似曾相熟,比如常听到浏览器解析http响应构建的DOM对象。DOM对象是个语言无关的,保存XML或者HTML文档的树状结构。
mariolu
2019/11/28
3.1K0
C++那些事之轻松解析json
本节推荐一个解析json的库,之前推荐过解析xml,未来将会推荐更多,帮助大家解读常用语法。
公众号guangcity
2020/07/02
2.9K0
C++中消息自动派发之一 About JSON
1. 闲序   游戏服务器之间通信大多采用异步消息通信。而消息打包常用格式有:google protobuff,facebook thrift, 千千万万种自定义二进制格式,和JSON。前三种都是二进制格式,针对C++开发者都是非常方便的,效率和包大小(数据冗余度)也比较理想。而JSON是字符串协议,encode和decode需要不小的开销。500字节json字符串解析大约需要1ms左右。JSON在脚本语言中非常常见,比如WEB应用、Social Game等,原因是web应用通过多进程分摊了JSON解析的C
知然
2018/03/09
1.3K0
js将json字符串转换成json对象_java中将字符串转换为json
private static String dateformat = “yyyy-MM-dd hh:mm:ss”;
全栈程序员站长
2022/11/08
5.3K0
ijst:基于反射的 C++ JSON 反序列化库
ijst (iJsonStruct) 一个是 C++ Json 序列化/反序列化库:
h46incon
2018/08/20
3.5K0
【C++】开源:基于cjson库的json数据处理
项目Github地址:https://github.com/DaveGamble/cJSON
DevFrank
2024/07/24
2270
【C++】开源:基于cjson库的json数据处理
【C++11】:原始字符串字面量(Json字符串表达更方便)
因为普通字符串如果要有特定的字符(   "  字符    或者   \   字符),就要进行转移(\进行转义),不然就是特殊的含义。
用户11396661
2025/03/20
640
【C++11】:原始字符串字面量(Json字符串表达更方便)
Event Store框架探究
摘要:   游戏开发中,经常会越到千奇百怪的Bug。后台程序都是以demon 方式运行,要么GDB,要么Log。一些确定性的bug可以直接使用GDB调试,比如特定请求会Crash。如果是运行一段时间,Bug才会出现,无明显规律,那么也只能使用Log了。但是从成千上万条日志中Grep、分析、定位,然后修改代码、测试,这个过程效率极其低,有的时候挫折感倍强,想骂娘都。经过一些总结后,我们希望程序能够具有完整跟踪用户行为的功能。用户的行为被完整的记录下来,针对领域对象提供类似“快照”的功能,当程序出现问题时,我们
知然
2018/03/09
1.1K0
Event Store框架探究
jsoncpp初探
首先说一下JSON。JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言,易于人阅读和编写,同时也易于机器解析和生成,一般用于网络传输。
恋喵大鲤鱼
2018/08/03
2.2K0
jsoncpp初探
C++之rapidjson构造Json数据集合
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
程序手艺人
2019/10/28
1.4K0
Qt平台下使用QJson构建JSON字符串
上两篇文章介绍了使用cJSON库解析和构建JSON字符串和Qt平台下使用QJson解析JSON字符串
单片机点灯小能手
2020/07/16
1.5K0
相关推荐
C++的RapidJSON库的分析和实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档