高效的 C++ JSON 解析、生成器 RapidJSON

news2024/11/19 17:39:55

简介

  RapidJSON是一个高效的C++ JSON解析器和生成器。它专注于性能和易用性,使得处理JSON数据变得简单和快速。RapidJSON支持现代的JSON特性,如嵌套对象、数组、Unicode编码和注释。它的API简洁易用,可以轻松解析和生成JSON数据。无论你的项目需要处理大量的JSON数据,还是只需要解析或生成少量的JSON数据,RapidJSON都能提供出色的性能和便利的API,成为你的理想选择。

说明文档

https://rapidjson.org/zh-cn/md_doc_pointer_8zh-cn.html

下载地址

https://github.com/Tencent/rapidjson/

安装

RapidJSON 是只有头文件的 C++ 库。只需把 include/rapidjson 目录复制至系统或项目的 include 目录中。或者如果是用vs可以设置包含目录
在这里插入图片描述

Value 及 Document

每个 JSON 值都储存为 Value 类,而 Document 类则表示整个 DOM,它存储了一个 DOM 树的根 Value。
RapidJSON 的所有公开类型及函数都在 rapidjson 命名空间中。

查询 Value

  • 头文件和命名空间
#include "rapidjson/document.h"
using namespace rapidjson;
  1. json字符串
{
    "hello": "world",
    "t": true ,
    "f": false,
    "n": null,
    "i": 123,
    "pi": 3.1416,
    "a": [1, 2, 3, 4]
}
  1. 代码
    将JSON字符串,解析至document 中,成为一棵 DOM 树
#include <iostream>  
#include "rapidjson/document.h"
using namespace std;
using namespace rapidjson;

int main()
{
	string json = "{ \"hello\": \"world\", \"t\": true, \"f\": false, \"n\": null, \"i\": 123, \"pi\": 3.1416, \"a\": [1, 2, 3, 4] }";
	Document document;
	document.Parse(json.c_str());

	cin.get();
	return 0;
}
  1. DOM树
    在这里插入图片描述
  2. 判断根是不是 Object
assert(document.IsObject());

assert 是一个判断语句。参数为false时,会导致程序终止。在生产环境中,要使用其他方法来处理这种情况,例如通过返回错误代码或抛出异常。

  1. 获取成员值
  • 让我们查询一下根 Object 中有没有 “hello” 成员。
assert(document.HasMember("hello"));
  • 验证类型
assert(document["hello"].IsString());
  • 根据类型获取其值
printf("hello = %s\n", document["hello"].GetString());

输出:world

  • JSON True/False 值是以 bool 表示的。
assert(document["t"].IsBool());
printf("t = %s\n", document["t"].GetBool() ? "true" : "false");

输出:true

  • JSON Null 值可用 IsNull() 查询。
printf("n = %s\n", document["n"].IsNull() ? "null" : "?");

输出:null

  • JSON Number 类型表示所有数值。然而,C++ 需要使用更专门的类型。
assert(document["i"].IsNumber());
assert(document["pi"].IsNumber());

assert(document["i"].IsInt());   
printf("i = %d\n", document["i"].GetInt());

assert(document["pi"].IsDouble());
printf("pi = %g\n", document["pi"].GetDouble());

整型123、浮点型3.1416使用IsNumber()判断都是true

输出:
i = 123
pi = 3.1416

  • JSON Array 包含一些元素。
// 使用引用来连续访问,方便之余还更高效。
const Value& a = document["a"];
assert(a.IsArray());
for (SizeType i = 0; i < a.Size(); i++) // 使用 SizeType 而不是 size_t
        printf("a[%d] = %d\n", i, a[i].GetInt());

输出:
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4

注意,RapidJSON 并不自动转换各种 JSON 类型。例如,对一个 String 的 Value 调用 GetInt() 是非法的,其行为是未定义的.

查询 Array

SizeType 是 unsigned int 的别名。在多数系统中,Array 最多能存储 2^32-1 个元素。
Array 与 std::vector 相似,除了使用索引,也可使用迭代器来访问所有元素。

for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
    printf("%d ", itr->GetInt());

当使用 C++11 功能时,你可使用范围 for 循环去访问 Array 内的所有元素。

for (auto& v : a.GetArray())
		printf("%d ", v.GetInt());

查询 Object

用迭代器去访问所有 Object 成员:

 vector<string> kTypeNames = {"Null", "False", "True", "Object", "Array", "String", "Number"};  
 
for (Value::ConstMemberIterator itr = document.MemberBegin();
    itr != document.MemberEnd(); ++itr)
{
    printf("Type of member %s is %s\n",itr->name.GetString(), kTypeNames[itr->value.GetType()].c_str());
}

输出:
Type of member hello is String
Type of member t is True
Type of member f is False
Type of member n is Null
Type of member i is Number
Type of member pi is Number
Type of member a is Array

当使用 C++11 功能时,你可使用范围 for 循环去访问 Object 内的所有成员。

for (auto& m : document.GetObject())
    printf("Type of member %s is %s\n",
        m.name.GetString(), kTypeNames[m.value.GetType()]);

判断对象是否存在

HasMember()方法,会导致两次查找:

	if(document.HasMember("hello"))
		printf("%s\n", document["hello"].GetString());

FindMember()方法,更好:

	Value::ConstMemberIterator itr = document.FindMember("hello");
	if (itr != document.MemberEnd())
		printf("%s\n", itr->value.GetString());

查询 Number

查检
提取
描述
bool IsUint()unsigned GetUint()32 位无符号整数
bool IsInt()int GetInt()32 位有符号整数
bool IsUint64()uint64_t GetUint64()64 位无符号整数
bool IsInt64()int64_t GetInt64()64 位有符号整数
bool IsDouble()double GetDouble()64 位双精度浮点数

注意,一个整数可能用几种类型来提取,而无需转换。例如,一个名为 x 的 Value 包含 123,那么 x.IsInt() == x.IsUint() == x.IsInt64() == x.IsUint64() == true。但如果一个名为 y 的 Value 包含 -3000000000,那么仅会令 x.IsInt64() == true

当要提取 Number 类型,GetDouble() 是会把内部整数的表示转换成 double。注意 int 和 unsigned 可以安全地转换至 double,但 int64_t 及 uint64_t 可能会丧失精度( int64_t 最大值有19 位有效数字,uint64_t最大值有 20 位有效数字,都超过了 double 15位有效数字的限制)。

查询 String

c++string字符串把 '\0' 作为结束符号,如果json的值中带有这个字符,则需要用GetStringLength()获取正确的长度。

	if (document.HasMember("hello") && document["hello"].IsString())
	{
		SizeType len = document["hello"].GetStringLength();
		string str(document["hello"].GetString(), len);
		printf("%s %d\n", str.c_str(), len);
	}

输出:
world 5

比较两个 Value

直接使用 == 及 != 比较两个 Value。当两个 Value 的类型及内容相同,它们才当作相等。也可以比较 Value 和它的原生类型值。例子:

if (document["hello"] == document["n"]) /*...*/;    // 比较两个值
if (document["hello"] == "world") /*...*/;          // 与字符串字面量作比较
if (document["i"] != 123) /*...*/;                  // 与整数作比较
if (document["pi"] != 3.14) /*...*/;                // 与 double 作比较

Array/Object 顺序以它们的元素/成员作比较。当且仅当它们的整个子树相等,它们才当作相等。
另外需要注意的是若一个 Object 含有重复命名的成员,它与任何 Object 作比较都总会返回 false。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1124483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“菜鸟”程序员逆袭:独立开发iOS音乐应用,年底参加Amazon DeepRacer 全球锦标赛

“致一年前的小木土&#xff1a;任务完成。” 6月30日&#xff0c;在获得2023 Amazon DeepRacer自动驾驶赛车企业总决赛中国区冠军三天后的深夜&#xff0c;杜键文发了这条朋友圈&#xff0c;并配上比赛现场的9张图。 “小木土”是杜键文的网名&#xff0c;取其姓氏&#xff…

【【萌新的FPGA学习之水 一水到底 】】

萌新的FPGA学习之水 一水到底 重读实验给我印象最深的2点是我们面对的设计需要使得时序自动切换 那么我们将切换时序的时钟装入另一个每隔0.5s变换一次的参数上 下附上代码 module key_led(input sys_clk , //系统时钟input sys_rst_n , //系统复位&#xff0c;低电平有效 inp…

扩散模型学习——代码学习

文章目录 引言正文UNet网络结构训练方法DDPM采样方法讲解Context上下文信息添加DDIM的方法详解 总结参考 引言 这是第一次接触扩散模型&#xff0c;为了学习&#xff0c;这里好好分析一下他的代码 正文 UNet网络结构 这部分主要是定义一下网络结构&#xff0c;以及相关的网…

免费领取!TikTok Shop “全托管”黑五大促官方备战指南来啦!

黑五网一大促即将来袭&#xff0c;自“全托管”模式上线以来&#xff0c;TikTok for Business在沙特阿拉伯和英国市场开展了古尔邦节大促、夏季大促、返校季大促等活动&#xff0c;今年更是会借着黑五网一大促之际&#xff0c;首次覆盖美国市场&#xff0c;为全托管商家带来全球…

k8s的coreDNS添加自定义hosts

1.ack的hosts不会继承宿主机的hosts&#xff0c;而工作中有一个域名默认是走内网解析&#xff0c;内网被限制访问了&#xff0c;只能在coreDNS中加一个hosts解析域名 2.编辑configmap (coredns) kubectl edit configmap -n kube-system coredns 增加hosts节点 Corefile: |.:53…

由浅到深 : Self-Attention (自注意力机制)

Self-Attention 看到下面的第一个saw是动词&#xff0c;第二个saw是名词。 因为第一个saw和第二个saw在形式上没有任何差别。如果任务是进行词性的判断&#xff0c;把上面的词直接输入给神经网络&#xff0c;那么它肯定不能够正确分析。 想要正确分析词性&#xff0c;那么该…

谈谈你对Spring6.0的理解

谈谈你对Spring6.0的理解 一&#xff0c;介绍 Spring 6.0是Spring框架的一个重要版本&#xff0c;它提供了许多新特性和改进&#xff0c;以帮助开发者更高效地完成工作。以下是我对Spring 6.0的一些理解&#xff1a; 反应式编程支持&#xff1a;Spring 6.0对反应式编程提供了…

Pico示波器 汽车振动异响(NVH)解决方案

汽车振动异响故障可能有多个潜在原因&#xff0c;包括发动机、传动系统、悬挂系统、制动系统等等。技师需要对汽车各个方面有全面的了解&#xff0c;才能更好地进行故障排查。 振动和异响可能由多个因素引起。例如&#xff0c;可能是零部件损坏、松脱、磨损或者不正确安装。这…

ResNet: Deep Residual Learning for Image Recognition(CVPR 2015)

正常来说&#xff0c;plain网络&#xff08;简单的堆叠层数&#xff09;会随着网络的加深错误率变低的&#xff0c;但事实上训练和测试错误率都升高了&#xff0c;这就是网络的退化问题。 此外&#xff0c;网络加深会出现梯度消失或梯度爆炸&#xff0c;妨碍收敛&#xff0c;但…

HarmonyOS 音频开发指导:使用 AudioRenderer 开发音频播放功能

AudioRenderer 是音频渲染器&#xff0c;用于播放 PCM&#xff08;Pulse Code Modulation&#xff09;音频数据&#xff0c;相比 AVPlayer 而言&#xff0c;可以在输入前添加数据预处理&#xff0c;更适合有音频开发经验的开发者&#xff0c;以实现更灵活的播放功能。 开发指导…

node-sass安装报错

node-sass安装竟然报了python的错 先说最终解决方案 将node换成14版本 声明&#xff1a;个人总结&#xff0c;思路到哪写到哪&#xff0c;不喜请轻喷&#x1f602; 参考 https://blog.csdn.net/ccm_2354586864 可恶的node-sass让我不得不在周末自愿加班&#x1f620; 我的…

优化mybatisPlus批量新增,新增mapper层批量新增方法,附带代码生成vm模板。

文章目录 一、主题二、效果展示三、mybatis-plus源码分析四、优化思路五、代码优化方法一&#xff1a;修改批量新增SQL方法二&#xff1a;使用insertBatchSomeColumn 方法 一、主题 经发现&#xff0c;mybatisPlus只有Service中存在saveBatch()方法&#xff0c;而Mapper中不存在…

博客后台模块续更(五)

十一、后台模块-菜单列表 菜单指的是权限菜单&#xff0c;也就是一堆权限字符串 1. 查询菜单 1.1 接口分析 需要展示菜单列表&#xff0c;不需要分页。可以针对菜单名进行模糊查询。也可以针对菜单的状态进行查询。菜单要按照父菜单id和orderNum进行排序 请求方式 请求路径…

从0开始学云计算之服务器:服务的定义,特点,应用场景,分类

服务器定义 服务器是计算机的一种。它比普通计算机运行速度更快、负载更高且价格更高。 服务器的英文名称为“Server”&#xff0c;是指在网络上提供各种服务的高性能计算机。作为网络的节点&#xff0c;存储、处理网络上80%的数据、信息&#xff0c;因此也被称为x络的灵魂。 …

三、机器学习基础知识:Python常用机器学习库(Pandas)

文章目录 1、Pandas2、Series数据结构2.1 Series的创建2.2 Series的索引与访问2.3 Series的常见操作 3、DataFrame对象3.1 DataFrame的创建与索引3.2 DataFrame的访问3.3 DataFrame的常见操作 4、数据对齐5、缺失数据处理6、Pandas存取文件 1、Pandas Pandas 库是以Numpy库为基…

互联网医院牌照|互联网医院牌照资质申请流程和所需材料

那么不同的企业基于不同的业务板块&#xff0c;所需要搭建的互联网医院也存在差异&#xff0c;平衡好自身业务及互联网医疗建设二者间的关系&#xff0c;是企业建设互医的基础需求&#xff0c;那么互联网医院牌照办理流程和材料都包含哪些呢&#xff1f;接下来就给大家介绍下。…

短视频矩阵系统软件源码

短视频矩阵系统软件源码 视频成为获得免费流量最便宜的渠道&#xff0c;平台给所有视频最基础的保底流量。如果按照一个视频最低500流量计算&#xff0c;5个账户就是2500的流量&#xff0c;200个视频就是50W流量&#xff0c;如果从其他渠道获得50W流量是个很困难的事情。短视频…

第四章 文件管理 三、文件目录

目录 一、文件控制块 1、定义&#xff1a; 2、要进行哪些操作 &#xff08;1&#xff09;搜索: &#xff08;2&#xff09;创建文件: &#xff08;3&#xff09;删除文件: &#xff08;4&#xff09;显示目录: &#xff08;5&#xff09;修改目录: 二、目录结构 1、单…

QSOP24封装的语音芯片优势列举

1. 封装紧凑&#xff1a;QSOP24封装采用了更小的封装尺寸&#xff0c;相比于其他大型封装&#xff0c;它的体积更小、尺寸更紧凑。这使得它在空间受限的应用中更加适用&#xff0c;可以方便地集成到小型或薄型设备中&#xff0c;提供更高的设计灵活性。 2. 强大的功能&#xf…

Go之流程控制大全: 细节、示例与最佳实践

引言 在计算机编程中&#xff0c;流程控制是核心的组成部分&#xff0c;它决定了程序应该如何根据给定的情况执行或决策。以下是Go语言所支持的流程控制结构的简要概览&#xff1a; 流程控制类型代码if-else条件分支if condition { } else { }for循环for initialization; con…