当前位置: 首页 > article >正文

RapidJSON 处理 JSON(高性能 C++ 库)(四)

第四部分:RapidJSON 处理 JSON(高性能 C++ 库)

📢 快速掌握 JSON!文章 + 视频双管齐下 🚀

如果你觉得阅读文章太慢,或者更喜欢 边看边学 的方式,不妨直接观看我录制的 RapidJSON 课程视频!🎬 视频里会用更直观的方式讲解 RapidJSON 的核心概念、实战技巧,并配有动手演示,让你更高效地掌握 RapidJSON 的处理方法!

当然,如果你喜欢深度阅读,这篇文章会帮助你系统地理解 RapidJSON,从基础到进阶!无论你选择哪种方式,最终目标都是让你成为 RapidJSON 处理的高手!💪

🎥 点击这里观看视频 👉 视频链接

一:RapidJSON 库概述与环境配置

1.1 RapidJSON 是什么?

​ RapidJSON 是一个高效可移植的 C++ JSON 解析库,专为高性能应用设计。它具有以下特点:

超快:比许多 JSON 库(如 cJSON、JSONCPP)解析速度更快,适用于高性能应用。

全功能:支持DOM(文档对象模型)解析和SAX(流式解析),适用于不同场景。

零依赖:仅使用 C++ 标准库,无需额外的库支持。

1.2 RapidJSON 适用场景

大规模数据处理(如日志分析、金融数据解析)。

游戏开发(解析游戏配置)。

嵌入式开发(存储和解析 IoT 设备 JSON 数据)。

高并发服务器(解析 API 响应,提高吞吐量)。

1.3 下载和安装 RapidJSON

方法 1:使用 vcpkg安装(推荐)(Windows / Linux)

#如果使用 vcpkg 作为包管理工具,可以直接安装:
vcpkg install rapidjson

方法 2:使用系统包管理器

  • Ubuntu/Debian
sudo apt install rapidjson-dev
  • Mac(Homebrew)
brew install rapidjson

安装后,在 CMakeLists.txt 中添加:

find_package(RapidJSON CONFIG REQUIRED)

然后在代码中:

#include <rapidjson/document.h>

方法 2:手动下载

1.从 RapidJSON GitHub 下载源码。

访问该页面,点击绿色的 Code 按钮,选择 Download ZIP,然后解压缩到你本地的某个目录,或者使用 Git 命令进行克隆:

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

2.将 include目录加入项目:

#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h" // 用于格式化输出
#include "rapidjson/stringbuffer.h" // 用于缓存输出

这些头文件提供了 RapidJSON 主要功能的接口:

  • document.h:用于解析 JSON 数据并创建 JSON 对象。

  • prettywriter.h:用于将 JSON 数据格式化为易读的字符串。

  • stringbuffer.h:用于将 JSON 数据写入字符串。

3.RapidJSON 仅包含头文件,因此无需编译。

​ RapidJSON 是只有头文件的 C++ 库。只需把 include/rapidjson 目录复制至系统或项目的 include 目录中。

1.4 在 C++ 项目中集成 RapidJSON(CMake / vcpkg)

如果项目使用 CMake,可以这样安装:

  1. 在 CMakeLists.txt中添加:

    include(FetchContent)
    FetchContent_Declare(rapidjsonGIT_REPOSITORY https://github.com/Tencent/rapidjson.gitGIT_TAG master
    )
    FetchContent_MakeAvailable(rapidjson)
    
  2. 然后在代码中 #include <rapidjson/document.h> 直接使用。

使用示例:

#include <iostream>
#include <rapidjson/document.h>int main() {const char* json = R"({"name": "Alice", "age": 25, "skills": ["C++", "Python"]})";// 解析 JSONrapidjson::Document doc;doc.Parse(json);// 读取数据if (doc.HasMember("name") && doc["name"].IsString()) {std::cout << "Name: " << doc["name"].GetString() << std::endl;}if (doc.HasMember("age") && doc["age"].IsInt()) {std::cout << "Age: " << doc["age"].GetInt() << std::endl;}if (doc.HasMember("skills") && doc["skills"].IsArray()) {std::cout << "Skills: ";for (auto& skill : doc["skills"].GetArray()) {std::cout << skill.GetString() << " ";}std::cout << std::endl;}return 0;
}

二:使用 RapidJSON 解析 JSON

  • 解析 JSON 字符串为 RapidJSON DOM
  • 访问 JSON 对象的键值对和数组元素
  • 使用 SAX 解析大 JSON 文件(事件驱动方式)
2.1 解析 JSON 对象
2.1.1 解析基本 JSON

目标 JSON

{"name": "张三","age": 30,"married": true
}

C++ 代码

#include <iostream>
#include "rapidjson/document.h"int main() {const char* json = R"({"name": "张三", "age": 30, "married": true})";rapidjson::Document doc;if (doc.Parse(json).HasParseError()) {cout << "JSON 解析失败!" << endl;return -1;}std::cout << "姓名: " << doc["name"].GetString() << endl;cout << "年龄: " << doc["age"].GetInt() << endl;cout << "已婚: " << (doc["married"].GetBool() ? "是" : "否") << endl;return 0;
}

输出

姓名: 张三
年龄: 30
已婚: 是
2.1.2 解析 JSON 数据并输出
#include <iostream>
#include "rapidjson/document.h"int main() {// JSON 字符串const char* json = R"({"name": "John","age": 30,"city": "New York"})";// 创建 RapidJSON 文档对象rapidjson::Document document;// 解析 JSON 字符串if (document.Parse(json).HasParseError()) {std::cerr << "JSON 解析失败!" << std::endl;return 1;}// 检查并输出每个成员if (document.HasMember("name") && document["name"].IsString()) {std::cout << "Name: " << document["name"].GetString() << std::endl;}if (document.HasMember("age") && document["age"].IsInt()) {std::cout << "Age: " << document["age"].GetInt() << std::endl;}if (document.HasMember("city") && document["city"].IsString()) {std::cout << "City: " << document["city"].GetString() << std::endl;}return 0;
}

代码说明:

  1. 创建 RapidJSON 文档对象:
    • rapidjson::Document document;:这是用来解析 JSON 数据的对象。它内部会保存 JSON 数据的结构。
  2. 解析 JSON 字符串:
    • document.Parse(json):解析给定的 JSON 字符串。如果解析成功,返回值为 true,否则会返回错误信息。
  3. 检查 JSON 成员并输出:
    • HasMember("name"):检查 JSON 对象是否包含名为 "name" 的字段。
    • document["name"].GetString():从 JSON 对象中提取 "name" 字段的值,并作为字符串输出。
  4. 输出解析结果:
    • 根据 JSON 中的字段,程序将输出每个字段的内容,例如 "name": "John" 将输出 Name: John

输出结果:

Name: John
Age: 30
City: New York

2.1.3 进一步扩展

你可以扩展这个示例,处理更多复杂的 JSON 数据,甚至解析嵌套的 JSON 对象或数组。

解析嵌套 JSON 对象

假设我们有一个更复杂的 JSON 字符串,包含嵌套的 JSON 对象:

{"name": "John","age": 30,"address": {"street": "5th Avenue","city": "New York"}
}

你可以如下解析:

#include <iostream>
#include "rapidjson/document.h"int main() {const char* json = R"({"name": "John","age": 30,"address": {"street": "5th Avenue","city": "New York"}})";rapidjson::Document document;if (document.Parse(json).HasParseError()) {std::cerr << "JSON 解析失败!" << std::endl;return 1;}// 输出基础字段std::cout << "Name: " << document["name"].GetString() << std::endl;std::cout << "Age: " << document["age"].GetInt() << std::endl;// 解析嵌套的 JSON 对象 "address"if (document.HasMember("address") && document["address"].IsObject()) {const rapidjson::Value& address = document["address"];std::cout << "Street: " << address["street"].GetString() << std::endl;std::cout << "City: " << address["city"].GetString() << std::endl;}return 0;
}

输出结果:

Name: John
Age: 30
Street: 5th Avenue
City: New York

总结:

  • 使用 RapidJSON 可以方便地解析 JSON 字符串,提取其中的数据,并进行相应的处理。
  • 解析时需要检查字段是否存在,避免访问不存在的字段引发错误。
  • 可以解析简单的 JSON 字符串,也可以处理嵌套的 JSON 对象,甚至是数组等复杂数据结构。

2.2 解析 JSON 数组

📌 示例 2:解析数组

目标 JSON

{"cities": ["北京", "上海", "广州"]
}

C++ 代码

const char* json = R"({"cities": ["北京", "上海", "广州"]})";
Document doc;
doc.Parse(json);const Value& cities = doc["cities"];
for (SizeType i = 0; i < cities.Size(); i++) {cout << "城市 " << i + 1 << ": " << cities[i].GetString() << endl;
}

输出

城市 1: 北京
城市 2: 上海
城市 3: 广州
2.3 解析并格式化输出 JSON 数据

RapidJSON 提供了 PrettyWriter 类,允许你对 JSON 数据进行格式化输出,加入缩进、换行等

代码示例:解析并格式化输出 JSON 数据

#include <iostream>
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"int main() {// 原始 JSON 字符串const char* json = R"({"name": "John","age": 30,"city": "New York"})";// 创建 RapidJSON 文档对象rapidjson::Document document;// 解析 JSON 字符串if (document.Parse(json).HasParseError()) {std::cerr << "JSON 解析失败!" << std::endl;return 1;}// 创建一个 StringBuffer 用于保存格式化后的 JSON 字符串rapidjson::StringBuffer buffer;// 创建 PrettyWriter 对象,传入 StringBufferrapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);// 将 JSON 数据格式化并输出到 StringBufferdocument.Accept(writer);

相关文章:

RapidJSON 处理 JSON(高性能 C++ 库)(四)

第四部分:RapidJSON 处理 JSON(高性能 C++ 库) 📢 快速掌握 JSON!文章 + 视频双管齐下 🚀 如果你觉得阅读文章太慢,或者更喜欢 边看边学 的方式,不妨直接观看我录制的 RapidJSON 课程视频!🎬 视频里会用更直观的方式讲解 RapidJSON 的核心概念、实战技巧,并配有…...

80. Linux内核定时器实验

一、Linux内核定时器原理 1.1、内核时间管理 1、Cortex-M内核使用systick作为系统定时器。 2、硬件定时器、软件定时器&#xff0c;原理是依靠系统定时器来驱动。 3、linux内核频率可以配置&#xff0c;图形化界面配置。 4、重点&#xff0c;HZ表示系统节拍率&#xff0c; 1.…...

Java 可变参数全解析:动态参数传递的实践指南

Java 可变参数全解析&#xff1a;动态参数传递的实践指南 一、可变参数&#xff1a;Java 方法的灵活扩展 在狂神说 Java 第 49 集课程中&#xff0c;我们系统学习了 Java 可变参数的核心原理。作为 Java SE 5 引入的重要特性&#xff0c;可变参数允许方法接受动态数量的输入&…...

C++类与对象(上):从入门到实践

目录 一、引言 二、面向过程和面向对象初步认识 2.1 面向过程编程 2.2 面向对象编程 三、类的引入 四、类的定义 4.1 定义格式 4.2 定义方式 4.3 成员变量命名规则建议 五、类的访问限定符及封装 5.1 访问限定符 5.2 封装 六、类的作用域 七、类的实例化 7.1 概念…...

Lumerical ------ Edge coupler design

Lumerical ------ Edge coupler design 引言正文无 Si Substrate 的仿真步骤有 Si Substrate 的仿真步骤引言 本文,我们将使用官方提供的 Edge coupler 设计教程,但是中间会带有作者本人的设计的感悟。 正文 无 Si Substrate 的仿真步骤 打开 Edge_Coupler_No_Substrate.l…...

大语言模型本质上还是自动化,而不是智能化

大语言模型本质上仍然是自动化或高级自动化&#xff0c;而非真正的智能化&#xff0c;原因可以从以下几个方面进行分析&#xff1a;1、自动化与智能化的本质区别自动化&#xff1a;大语言模型通过预训练和微调&#xff0c;基于大量数据和规则生成输出。它的行为是基于输入数据的…...

cmake 中的命令

命令描述示例capabilities报告 CMake 内置的功能&#xff0c;以 JSON 格式输出cmake -E capabilitiescat连接文件并将其内容打印到标准输出cmake -E cat file1.txt file2.txtchdir在指定目录中运行命令cmake -E chdir /path/to/dir commandcompare_files比较两个文件是否相同cm…...

python数据结构——链表、栈、队列

一、思维梳理&#xff1a; 二、双向循环链表&#xff1a; class Node:def __init__(self,data):self.data dataself.next Noneself.prev Noneclass DoubleLink:def __init__(self):self.size 0self.head Nonedef is_empty(self):return self.size 0def add_end(self,dat…...

centos操作系统如何更换yum镜像源

CentOS Linux 是一个免费提供的、社区支持的Linux发行版,由CentOS项目社区贡献者开发、分发和维护。2020年CentOS项目宣布将把全部投资转移到CentOS Stream,作为即将发布的 Red Hat Enterprise Linux版本的上游开发平台。因此,CentOS Linux更新和发布将在2021年至2024年期间…...

【Linux篇】自主Shell命令行解释器

&#x1f4cc; 个人主页&#xff1a; 孙同学_ &#x1f527; 文章专栏&#xff1a;Liunx &#x1f4a1; 关注我&#xff0c;分享经验&#xff0c;助你少走弯路&#xff01; 文章目录 1. 获取用户名的接口2. 等待用户输入接口3. 将上述代码进行面向对象式的封装4. 命令行解析5.…...

Tomcat 部署 Jenkins.war 详细教程(含常见问题解决)

在Tomcat中部署Jenkins.war文件是一个相对简单的过程&#xff0c;以下是详细步骤&#xff1a; 1. 准备工作 确保已安装JDK&#xff1a;Jenkins需要Java环境&#xff0c;建议安装JDK 8或更高版本。 下载Jenkins.war&#xff1a;https://pan.quark.cn/s/c4fd7711a1b3 下载Tomc…...

我的创作纪念日-一周年

目录 机缘 收获 日常 成就 憧憬 机缘 时光荏苒&#xff0c;转行计算机已经是第5个年头了。从Python入门&#xff0c;到C入土&#xff0c;兜兜转转&#xff0c;发现自己也只是初窥门径&#xff0c;习得皮毛。我从6年前开始潜水CSDN&#xff0c;学习各路大佬的技术经验&…...

多线程代码案例 - 1

目录 单例模式 1. 饿汉模式 2. 懒汉模式 单例模式与多线程 问题1 问题2 问题3 完&#xff01; 单例模式 单例模式是一种设计模式。 设计模式&#xff0c;是我们在编写代码时候的一种软性的规定&#xff0c;也就是说&#xff0c;我们遵守设计模式&#xff0c;代码的下限…...

display:none与visibility的区别

1. 是否占据空间 display: none&#xff1a;元素完全从文档流中移除&#xff0c;不占据任何布局空间。后续元素会“填补”它的位置。visibility:hidden&#xff1a;元素仍占据布局空间&#xff0c;但内容不可见&#xff08;类似透明占位符&#xff09;。 2.渲染与性能 displ…...

算法 | 基于蜣螂优化算法求解带时间窗的车辆路径问题(VRPTW)研究(附matlab代码)

基于蜣螂优化算法求解带时间窗的车辆路径问题(VRPTW)研究 🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏 摘要 带时间窗的车辆路径问题(VRPTW)是物流配送中的核心优化难题。本文提出一种基于蜣螂优化算法(Dung Beetle Optimizer, DBO)的求解方法,通过…...

开发体育赛事直播系统主播认证功能技术实现方案

该体育直播系统系统由东莞梦幻网络科技开发&#xff0c;使用 ThinkPHP 作为后端&#xff0c;Vue.js 作为 PC/H5 端框架&#xff0c;Java 和 Objective-C 分别用于安卓和 iOS 开发。 1、前端实现 (Vue.js) <template><div class"anchor-certification">…...

国产三维CAD「皇冠CAD」在汽车零部件领域建模教程:刹车片

本教程深度融合三维皇冠CAD&#xff08;CrownCAD&#xff09;的MBD&#xff08;Model-Based Definition&#xff09;设计理念&#xff0c;通过参数化建模、智能约束管理、动态装配验证等功能&#xff0c;实现数据驱动设计&#xff0c;精准解决了汽车制动系统中精密制动组件的设…...

基于指针的线程池

使用原线程池 当 push 和 pop的对象过大时&#xff0c;消耗时延过高&#xff0c;需优化线程池 采用 std::move&#xff08;&#xff09; unique_ptr的方法&#xff0c;能极大的减少时延&#xff0c; 实际就是避免了多次拷贝&#xff0c;直接使用指针。 代码实现 ThreadPool…...

GitHub与Gitee各是什么?它们的区别与联系是什么?

李升伟 整理 GitHub 介绍 GitHub 是一个基于 Git 的代码托管平台&#xff0c;主要用于版本控制和协作开发。它支持多人协作&#xff0c;提供代码托管、问题跟踪、代码审查、项目管理等功能。GitHub 是全球最大的开源社区&#xff0c;许多知名开源项目都在此托管。 主要功能&…...

SpringMvc获取请求数据

基本参数 RequestMapping("save5") ResponseBody public User save5(String name, int age) {User user new User();user.setName(name);user.setAge(age);return user; } 在url中将name与age进行编写&#xff0c;通过框架可以提取url中的name与age&#xff0c;这…...

简述竞赛经历在考研复试中的作用

文章目录 前言拟录取情况baichuicxyAshy佬齐总结回首展望 前言 随着就业形式的不断变化&#xff0c;竞赛奖项在就业中能起到的作用在逐步减弱。想拿到头部大厂实习面试资格&#xff0c;最低要区域赛银牌起步&#xff0c;当然这也仅仅是面试资格。 那么&#xff0c;竞赛经历在…...

大语言模型开发框架——LangChain

什么是LangChain LangChain是一个开发由语言模型驱动的应用程序的框架&#xff0c;它提供了一套工具、组件和接口&#xff0c;可以简化构建高级语言模型应用程序的过程。利用LangChain可以使应用程序具备两个能力&#xff1a; 上下文感知 将语言模型与上下文&#xff08;提示…...

Nginx 核心配置详解与性能优化最佳实践

1.什么是 Nginx&#xff1f; Nginx 是一个高性能的 Web 服务器和反向代理服务器。它轻量、高效&#xff0c;被广泛用于现代 Web 开发中。 2.为什么前端需要了解 Nginx&#xff1f; ★ 了解 本地开发&#xff1a;可以模拟生产环境 部署前端项目&#xff1a;作为静态文件服务器…...

机器学习的一百个概念(7)独热编码

前言 本文隶属于专栏《机器学习的一百个概念》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…...

用LLama factory时报类似Process 2504721 got signal: 1的解决方法

之前用nohup来远程跑LLama factory微调脚本&#xff0c;是没有问题的&#xff0c;但今天发现运行类似下面这个命令时&#xff0c; nohup llamafactory-cli train examples/train_qlora/qwen_lora.yaml 只要一关闭ssh session&#xff0c;就会终止训练&#xff0c;报类似&…...

解决 Git 通过 SSH 克隆仓库时自动转换为 HTTPS 的问题

解决 Git 通过 SSH 克隆仓库时自动转换为 HTTPS 的问题 在使用 Git 通过 SSH 协议克隆私有仓库时&#xff0c;如果遇到类似以下错误&#xff1a; fatal: unable to access https://itlab.stack.net:stack.git/: Could not resolve host: gitlab.stack这通常是因为 Git 配置错…...

从实用的角度聊聊Linux下文本编辑器VIM

本文从实用的角度聊聊Vim的常用命令。何为实用&#xff1f;我举个不实用的例子大家就明白了&#xff0c;用vim写代码。;) “vim是从 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序员中被广泛使用&#xff0c;和Emacs并列成…...

多电机显示并排序

多电机显示并排序 要实现根据后端传递过来的驱动电机数据的数量来显示不同数量的数据列表&#xff0c;我们可以使用 Vue 的 v-for 指令来遍历 driveMotorData 数组&#xff0c;并为每个驱动电机生成一个数据列表。这样&#xff0c;无论后端传来多少个驱动电机的数据&#xff0…...

佳能imageRUNNER 2206N基本参数及管理员密码

基本参数&#xff1a; 产品类型 激光数码复合机 颜色类型 黑白 涵盖功能 复印/打印/扫描 速度类型 低速 最大原稿尺寸 A3 复印/打印方式 激光静电转印方式 感光材料 OPC 显影系统 干式单组分显影 定影…...

社交类 APP 设计:打造高用户粘性的界面

在当今数字化时代&#xff0c;社交类APP已成为人们日常生活中不可或缺的一部分。然而&#xff0c;随着市场竞争的加剧&#xff0c;如何通过设计提升用户粘性成为社交类APP成功的关键。本文将从设计的关键要素、用户界面优化、功能创新、个性化体验以及持续优化等方面&#xff0…...