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);

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

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

相关文章

chromem-go + ollama + bge-m3 进行文档向量嵌入和查询

Ollama 安装 https://ollama.com/download Ollama 运行嵌入模型 bge-m3:latest ollama run bge-m3:latestchromem-go 文档嵌入和查询 package mainimport ("context""fmt""runtime""github.com/philippgille/chromem-go" )func ma…

【LeetCode 题解】数据库:180. 连续出现的数字

一、问题描述 给定一个Logs表&#xff0c;包含自增 ID 和数字字段&#xff1a; CREATE TABLE Logs (id INT PRIMARY KEY AUTO_INCREMENT,num VARCHAR(50) );要求编写 SQL 查询&#xff0c;找出所有至少连续出现三次的数字。例如&#xff1a; --------- | id | num | -------…

MaxEnt模型进阶:基于R语言自动化与GIS空间建模的物种栖息地精准预测

生物多样性的空间分布规律及其对环境变化的响应机制&#xff0c;是生态学与地理学研究的前沿议题。在气候变化加剧和人类活动干扰的双重压力下&#xff0c;如何精准预测物种潜在分布范围、识别关键环境驱动因子&#xff0c;已成为制定生物保护策略的核心科学问题。物种分布模型…

缓存雪崩解决方案:二级缓存VS随机TTL

背景 在学习缓存雪崩的时候&#xff0c;了解到有二级缓存和随机TTL两个解决方案&#xff0c;但是在学习之后&#xff0c;个人认为二级缓存本质上还是利用两层缓存的过期时间不一致来实现缓存过期时间随机化&#xff0c;这不就是和随机TTL一样吗&#xff0c;故有了这篇思考&…

Android View事件分发机制深度解析

在Android面试中&#xff0c;关于View事件分发机制的考察往往不仅限于基础流程&#xff0c;更关注底层原理、性能优化和实际应用场景。以下是针对面试的全面回答策略&#xff1a; 一、基础回答框架 核心三要素&#xff1a; 传递流程 "事件分发遵循Activity → Window →…

2829. k-avoiding 数组的最小总和

2829. k-avoiding 数组的最小总和 题目链接&#xff1a;2829. k-avoiding 数组的最小总和 代码如下&#xff1a; class Solution { public:int minimumSum(int n, int k) {int m min(k / 2, n);return (m * (m 1) (k * 2 n - m - 1) * (n - m)) / 2;} };

phpStorm2021.3.3在windows系统上配置Xdebug调试

开始 首先根据PHP的版本下载并安装对应的Xdebug扩展在phpStorm工具中找到设置添加服务添加php web page配置完信息后 首先根据PHP的版本下载并安装对应的Xdebug扩展 我使用的是phpStudy工具&#xff0c;直接在php对应的版本中开启xdebug扩展&#xff0c; 并在php.ini中添加如下…

LabVIEW永磁同步电机性能测试系统

开发了一种基于LabVIEW的永磁同步电机&#xff08;PMSM&#xff09;性能测试系统的设计及应用。该系统针对新能源汽车使用的电机进行稳态性能测试&#xff0c;解决了传统测试方法成本高、效率低的问题&#xff0c;实现了测试自动化&#xff0c;提高了数据的准确性和客观性。 ​…

谷粒商城:Redisson

目录 Redisson 整合Redisson RLock RReadWriteLock RSemaphore RCountDownLatch 优化三级分类缓存 缓存一致性问题 双写模式 失效模式 脏数据解决 Redisson 提供redis分布式锁&#xff08;Distributed locks with Redis&#xff09;的java客户端 整合Redisson 引入 …

Linux系统调用编程

目录 一. 理解进程和线程的概念。并在Linux系统下进行相应操作 1.1概念 1.1.1进程(Process) 1.1.2 线程(Thread) 1.2操作 1.2.1用 ps -a 命令查看系统中各进程的编号pid 1.2.2用kill 命令终止一个进程pid 二. 解释Linux的“虚拟内存管理”&#xff0c;它与stm32中的 真…

25-智慧旅游系统(协同算法)三端

介绍 技术&#xff1a; 基于 B/S 架构 SpringBootMySQLLayuivue 环境&#xff1a; Idea mysql maven jdk1.8 node 管理端功能 首页展示图表&#xff1a;以数据可视化方式展示关键业务数据。 用户管理&#xff1a;管理系统用户&#xff0c;包括查看、编辑等操作。 供应商管…

【stm32--HAL库DMA+USART+空闲中断不定长收发数据】

串口通信-Hal库实现不定长度收发&#xff0c;DMAUSART DMA串口STM32CUBEMX配置&#xff08;工程创建&#xff09;基础配置时钟配置工程配置 代码编写现象 DMA 在正式配置之前&#xff0c;我们先来一起简单了解一下DMA。DMA&#xff08;Direct Memory Access&#xff0c;直接内…

沉浸式体验测评|AI Ville:我在Web3小镇“生活”了一周

最近&#xff0c;我在朋友的推荐下&#xff0c;体验了 aivillebot 的项目。起初&#xff0c;我只是抱着试试看的心态&#xff0c;心想这不就是个 Web3 版的《星露谷物语》吗&#xff1f; 但是一周下来&#xff0c;我发现这个虚拟小镇也没那么简单——里面的居民不是目前端游或链…

FPGA学习-基于 DE2-115 板的 Verilog 分秒计数器设计与按键功能实现

一、核心功能设计 按键暂停/继续&#xff1a;通过KEY1控制计时状态 按键消抖处理&#xff1a;20ms消抖周期消除机械抖动 硬件资源分配&#xff1a;符合DE2-115开发板引脚规范 二、核心模块实现详解 1. 顶层模块&#xff08;counter&#xff09; module counter(input CL…

后端开发 SpringBoot 工程模板

概述 本篇文章主要记录如何开发一个通用的 SpringBoot 工程开发框架的项目模板&#xff0c;这样后续需要开发项目时就可以直接开箱直用了&#xff0c;省区了很多重复步骤。 项目初始化 创建项目&#xff1a; 按照我的选项来选&#xff0c;然后点击 create&#xff0c;等待文…

OpenCv(五)——边缘检测

目录 边缘检测 一、sobel算子边缘检测 &#xff08;1&#xff09;原理 1、X轴方向的边缘检测 2、Y轴方向的边缘检测 &#xff08;2&#xff09;sobel算子参数 &#xff08;3&#xff09;X轴方向边缘检测代码演示 1、显示圆的图像 2、x方向上的边缘检测&#xf…

无人机数据链技术及运行方式详解!

一、无人机数据链技术要点 1. 通信传输技术 频段选择&#xff1a; 常用频段包括 L波段&#xff08;1-2 GHz&#xff09;、C波段&#xff08;4-8 GHz&#xff09;、Ku/K波段&#xff08;12-40 GHz&#xff09;&#xff0c;不同频段在传输距离、带宽和抗干扰性间权衡。 低…

AI Agent 实战:搭建个人在线旅游助手

AI Agent 实战&#xff1a;搭建个人在线旅游助手 本次实验中&#xff0c;我们将继续探索 Agent 的提示词&#xff0c;学习更加规范的提示词撰写方法。 本实验中你将掌握的知识点 使用 Dify 构建 Agent 的方法结构化的提示词撰写技巧变量的使用方法 1. 准备 在新建 Agent 之…

检索增强生成(RAG):强化 AI 智能体的知识 “武装”

技术点目录 第一章、智能体(Agent)入门第二章、基于字节Coze 构建智能体(Agent)第三章、基于其他平台构建智能体&#xff08;Agent&#xff09;第四章、国内外智能体(Agent)经典案例详解第五章、大语言模型应用开发框架LangChain入门第六章、基于LangChain的大模型API接入第七章…

vscode 打开工程 看不到文件目录

vscode 打开工程 看不到文件目录 View->Explorer 快捷键&#xff1a;CtrlShiftE