C++ 中的 cJSON 解析库:用法、实现及递归解析算法与内存高效管理
在现代软件开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易于阅读和编写、易于机器解析和生成的特性,被广泛应用于各种场景。C++ 作为一种强大的编程语言,自然也需要一个高效的 JSON 解析库来处理 JSON 数据。cJSON 是一个流行的 C/C++ JSON 解析库,它以其简洁的设计和高效的性能赢得了开发者的青睐。本文将详细介绍 cJSON 的用法、实现原理,特别是其递归解析算法和内存高效管理机制。
一、cJSON 简介
cJSON 是一个轻量级的 JSON 解析库,支持 C 和 C++ 语言。它提供了简单易用的 API,可以方便地解析 JSON 数据和生成 JSON 字符串。cJSON 的特点包括:
-
轻量级:cJSON 的代码量较小,适合嵌入式系统和资源受限的环境。
-
高性能:cJSON 使用高效的解析算法,能够快速解析和生成 JSON 数据。
-
易用性:cJSON 提供了简洁的 API,开发者可以轻松上手。
-
灵活性:cJSON 支持多种数据类型,包括对象、数组、字符串、数字、布尔值和 NULL。
二、cJSON 的安装与基本用法
1. 安装 cJSON
cJSON 是一个开源项目,可以在 GitHub 上获取其源代码。以下是安装步骤:
-
克隆仓库:
git clone https://github.com/DaveGamble/cJSON.git -
编译:
cd cJSON make -
安装:
sudo make install
2. 基本用法
以下是一个简单的示例,展示如何使用 cJSON 解析 JSON 数据:
#include <iostream>
#include "cJSON.h"int main() {const char *json_string = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";// 解析 JSON 字符串cJSON *json = cJSON_Parse(json_string);if (json == nullptr) {std::cerr << "Error parsing JSON data." << std::endl;return -1;}// 获取 JSON 对象中的值cJSON *name = cJSON_GetObjectItem(json, "name");cJSON *age = cJSON_GetObjectItem(json, "age");cJSON *city = cJSON_GetObjectItem(json, "city");if (cJSON_IsString(name)) {std::cout << "Name: " << name->valuestring << std::endl;}if (cJSON_IsNumber(age)) {std::cout << "Age: " << age->valueint << std::endl;}if (cJSON_IsString(city)) {std::cout << "City: " << city->valuestring << std::endl;}// 释放 JSON 对象cJSON_Delete(json);return 0;
}
3. 生成 JSON 数据
cJSON 也支持生成 JSON 数据,以下是一个示例:
#include <iostream>
#include "cJSON.h"int main() {// 创建 JSON 对象cJSON *json = cJSON_CreateObject();// 添加键值对cJSON_AddStringToObject(json, "name", "John");cJSON_AddNumberToObject(json, "age", 30);cJSON_AddStringToObject(json, "city", "New York");// 将 JSON 对象转换为字符串char *json_string = cJSON_Print(json);// 输出 JSON 字符串std::cout << json_string << std::endl;// 释放 JSON 对象和字符串cJSON_Delete(json);free(json_string);return 0;
}
三、cJSON 的递归解析算法
cJSON 的解析算法是递归的,这意味着它能够处理嵌套的 JSON 数据结构。递归解析算法的核心思想是将 JSON 数据分解为多个小的 JSON 对象,然后逐个解析这些对象。
1. 递归解析的基本原理
递归解析的基本原理是通过递归函数来处理 JSON 数据的嵌套结构。以下是一个简单的递归解析函数的示例:
void parse_json(cJSON *json) {if (json == nullptr) return;// 遍历 JSON 对象的每个子项cJSON *item = nullptr;cJSON_ArrayForEach(item, json) {if (cJSON_IsObject(item)) {std::cout << "Parsing object..." << std::endl;parse_json(item); // 递归解析嵌套对象} else if (cJSON_IsArray(item)) {std::cout << "Parsing array..." << std::endl;parse_json(item); // 递归解析嵌套数组} else if (cJSON_IsString(item)) {std::cout << "String: " << item->valuestring << std::endl;} else if (cJSON_IsNumber(item)) {std::cout << "Number: " << item->valueint << std::endl;} else if (cJSON_IsBool(item)) {std::cout << "Bool: " << (item->valueint ? "true" : "false") << std::endl;} else if (cJSON_IsNull(item)) {std::cout << "Null" << std::endl;}}
}
2. 递归解析的优势
递归解析算法的优势在于其简洁性和灵活性。它能够轻松处理嵌套的 JSON 数据结构,而不需要复杂的循环和条件判断。此外,递归解析算法的代码通常更加清晰和易于维护。
四、cJSON 的内存高效管理
cJSON 在内存管理方面采用了高效的设计,主要体现在以下几个方面:
1. 动态内存分配
cJSON 使用动态内存分配来存储解析后的 JSON 数据。这意味着它会根据实际需要分配内存,从而避免了内存浪费。以下是一个示例,展示如何使用动态内存分配:
cJSON *json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "key", "value");
char *json_string = cJSON_Print(json);
在这个示例中,cJSON_CreateObject 和 cJSON_AddStringToObject 函数会动态分配内存来存储 JSON 对象和字符串。cJSON_Print 函数会将 JSON 对象转换为字符串,并动态分配内存来存储该字符串。
2. 内存释放
为了防止内存泄漏,cJSON 提供了 cJSON_Delete 和 free 函数来释放动态分配的内存。以下是一个示例:
cJSON_Delete(json);
free(json_string);
在这个示例中,cJSON_Delete 函数会释放 JSON 对象占用的内存,而 free 函数会释放 JSON 字符串占用的内存。
3. 内存管理的优势
cJSON 的内存管理设计具有以下优势:
-
高效性:动态内存分配和释放能够提高内存使用效率,避免内存浪费。
-
安全性:通过使用
cJSON_Delete和free函数,可以防止内存泄漏,提高程序的稳定性。 -
灵活性:动态内存分配和释放使得 cJSON 能够适应各种内存环境,包括嵌入式系统和资源受限的环境。
五、总结
cJSON 是一个功能强大且易于使用的 JSON 解析库,其递归解析算法和内存高效管理机制使其在处理 JSON 数据时表现出色。通过本文的介绍,希望读者能够对 cJSON 的用法、实现原理以及递归解析算法和内存高效管理有更深入的了解。在实际开发中,合理使用 cJSON 可以大大提高开发效率和程序性能。
相关文章:
C++ 中的 cJSON 解析库:用法、实现及递归解析算法与内存高效管理
在现代软件开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易于阅读和编写、易于机器解析和生成的特性,被广泛应用于各种场景。C 作为一种强大的编程语言,自然也需要一个高效的…...
websocket自动重连封装
websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…...
【C语言】球球大作战游戏
目录 1. 前期准备 2. 玩家操作 3. 生成地图 4. 敌人移动 5. 吃掉小球 6. 完整代码 1. 前期准备 游戏设定:小球的位置、小球的半径、以及小球的颜色 这里我们可以用一个结构体数组来存放这些要素,以方便初始化小球的信息。 struct Ball {int x;int y;float r;DWORD c…...
人工智能D* Lite 算法-动态障碍物处理、多步预测和启发式函数优化
在智能驾驶领域,D* Lite 算法是一种高效的动态路径规划算法,适用于处理环境变化时的路径重规划问题。以下将为你展示 D* Lite 算法的高级用法,包含动态障碍物处理、多步预测和启发式函数优化等方面的代码实现。 代码实现 import heapq impo…...
MySQL 8版本认证问题
目录 问题: Public Key Retrieval is not allowed原因: mysql 8.0 调整身份认证机制解决方法(三种) 问题: Public Key Retrieval is not allowed 连接MySQL8数据库的时候,报错内容如下:“Publi…...
Android 开发APP中参数配置与读取总结
以使用MQTT配置的参数 MQTT_BROKER_UR 、MQTT_USER_NAME、 MQTT_PASSWORD为例,说明配置设置和读取应用 项目中使用系统参数(如环境变量和gradle.properties文件中的属性)在Gradle构建脚本中,以下是一个详细的操作文档资料&…...
Scala 语法入门
Scala语法入门 1. 定义变量2. 定义方法3. 闭包4. 声明字符串5. 声明数组6. 声明集合7. 异常处理 1. 定义变量 (变量的类型在变量名之后等号之前声明) 不可变变量(val) 类似于 Java 中的 final 变量,即一旦赋值后,其值不能再被改…...
python中的flask框架
Flask 是一个用Python编写的轻量级Web应用框架 基于WSGI和Jinja2模板引擎 被称为“微框架”,其核心功能简单,不捆绑数据库管理、表单验证等功能,而是通过扩展来增加其他功能 Flask提供最基本的功能,不强制使用特定工具或库 通…...
【redis】缓存设计规范
本文是 Redis 键值设计的 14 个核心规范与最佳实践,按重要程度分层说明: 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析: 是否需要排序?: zset(有序集合)用…...
归一化与伪彩:LabVIEW图像处理的区别
在LabVIEW的图像处理领域,归一化(Normalization)和伪彩(Pseudo-coloring)是两个不同的概念,虽然它们都涉及图像像素值的调整,但目的和实现方式截然不同。归一化用于调整像素值的范围,…...
DeepSeek大模型本地部署实战
1. 下载并安装Ollama 打开浏览器:使用你常用的浏览器(如Chrome、Firefox等)访问Ollama的官方网站。无需特殊网络环境,直接搜索“Ollama”即可找到。 登录与下载:进入Ollama官网后,点击右上角的“Download…...
deepseek+kimi自动生成ppt
打开deepseek官网,输入详细的需求,让他生成个ppt 接着deepseek开始思考生成了 接着复制生成了的内容 打开kimi粘贴刚才deepseek生成的内容 可以一键生成啦,下载编辑使用吧...
集成SwanLab与HuggingFace TRL:跟踪与优化强化学习实验
文章目录 1. 引入SwanLabCallback2. 传入Trainer3. 完整案例代码4. GUI效果展示 TRL (Transformers Reinforcement Learning,用强化学习训练Transformers模型) 是一个领先的Python库,旨在通过监督微调(SFT)、近端策略优化…...
cefsharp131升级132测试(WinForms.NETCore)
一、升级(Nuget) 版本说明(readme):最低.NET Core3.1 (NET5.0) Visual C 2019 Redist 二、试运行、兼容性测试 三、后记说明 支持H264版本推荐版本63,79,84,88,100,111,125(支持h264和pdf预览) 其他H264版…...
Gitee AI上线:开启免费DeepSeek模型新时代
Gitee Al上线,并宣布开启免费DeepSeek模型的时代,这是一个非常值得关注的消息,因 为它标志着国内在AI领域的一个重要发展。DeepSeek模型是由阿里巴巴达摩院开发的,旨 在提供强大的自然语言处理(NLP)能力。下面是一些关于这一事件…...
nginx常用命令及补充
在Linux环境下nginx常用命令如下: 1、查看nginx版本号命令 nginx -v 2、查找nginx配置文件路径已经检查配置文件是否正确 nginx -t 3、查找nginx安装目录 which nginx 4、查看nginx进程 ps -ef|grep nginx 5、进入到nginx的sbin目录后,执行一下…...
自动驾驶---聊聊传统规控和端到端
1 背景 在自动驾驶领域中,端到端模型的兴起确实对传统的规划控制方法(笔者并不同意网上以Rule-Base称呼传统规控,传统的规控其实也使用了很多优化算法和博弈算法)产生了挑战,但这就意味着传统规控方法就完全没有应用了…...
node.js + html + Sealos容器云 搭建简易多人实时聊天室demo 带源码
node.js html Sealos容器云 搭建简易多人实时聊天室demo 带源码 前言功能介绍(demo演示)sealos官网配置node.js 编写服务端代码前端ui 调用接口整体项目目录部署到服务器 前言 hello哦盆友们,这次我们来十几行代码做一个超简单的多人聊天…...
OpenFeign远程调用返回的是List<T>类型的数据
在使用 OpenFeign 进行远程调用时,如果接口返回的是 List 类型的数据,可以通过以下方式处理: 直接定义返回类型为List Feign 默认支持 JSON 序列化/反序列化,如果服务端返回的是 List的JSON格式数据,可以直接在 Feig…...
PCL 计算多边形的面积【2025最新版】
目录 一、算法原理1、概述2、主要函数3、函数源码二、代码实现三、结果展示博客长期更新,本文最近更新时间为:2025年1月17日。 一、算法原理 1、概述 根据给定的多边形的点云计算多边形的面积 A r e a = 1 2 ∑...
Vue3+AI聊天室:如何实现消息自动滚动和流式响应?
Vue3AI聊天室:消息自动滚动与流式响应的工程实践 引言:当Vue3遇见AI对话 在构建现代化AI聊天应用时,流畅的交互体验往往比功能堆砌更重要。想象这样一个场景:用户发送问题后,界面立即开始逐字显示AI回复,同…...
如何使用Postman,通过Mock的方式测试我们的API
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 这篇文章将教会大家如何利用 postman,通过 Mock 的方式测试我们的 API。什么是 MockMock 是一项特殊的测试技巧,可以在没有依赖项的情况下进…...
一文读懂大模型,彻底告别 AI 焦虑 | 零门槛
今天,不聊复杂代码、不晒专业论文,用最直白的语言,带非技术背景的你彻底读懂大模型:核心逻辑、实用场景、产品选型,以及普通人应对AI浪潮的正确姿势。全文干货密集,建议收藏转发,读完摆脱AI焦虑…...
新手友好:在快马平台用mc、jc相关案例轻松上手前端开发
作为一个刚接触前端开发的新手,我最近在InsCode(快马)平台尝试做了一个特别适合练手的小工具——代码行数统计器。这个项目用最基础的HTML、CSS和JavaScript实现,但包含了前端开发的几个核心概念,特别适合想通过实际案例学习的朋友。 项目功能…...
5分钟搞定OpenClaw+GLM-4.7-Flash:星图平台一键部署体验
5分钟搞定OpenClawGLM-4.7-Flash:星图平台一键部署体验 1. 为什么选择云端部署OpenClaw 作为一个长期折腾本地AI部署的技术爱好者,我深知在个人电脑上配置OpenClaw的痛处。从Node.js版本冲突到模型权重下载失败,再到各种依赖库缺失…...
编译原理避坑指南:自顶向下语法分析的5个常见错误及解决方法
编译原理避坑指南:自顶向下语法分析的5个常见错误及解决方法 第一次接触自顶向下语法分析时,我盯着那个无限循环的递归文法整整三天没想明白——为什么明明按照教材步骤操作,程序却始终报错?直到助教指出我忽略了间接左递归的隐蔽…...
硬盘监控与健康管理:DiskInfo全方位使用指南
硬盘监控与健康管理:DiskInfo全方位使用指南 【免费下载链接】DiskInfo DiskInfo based on CrystalDiskInfo 项目地址: https://gitcode.com/gh_mirrors/di/DiskInfo 在数字化时代,硬盘故障可能导致珍贵数据永久丢失。DiskInfo作为一款基于Crysta…...
解锁汽车ECU诊断新可能:ECUBus-Pro开源工具的全场景应用指南
解锁汽车ECU诊断新可能:ECUBus-Pro开源工具的全场景应用指南 【免费下载链接】ECUBus ECU bus tool, UDS over CAN, CAN-FD, Ethernet and so on. 项目地址: https://gitcode.com/gh_mirrors/ec/ECUBus ECUBus-Pro是一款功能强大的开源汽车ECU开发工具&#…...
FLUX.1-dev像素生成器效果对比:不同Scale值对像素结构强度影响实测
FLUX.1-dev像素生成器效果对比:不同Scale值对像素结构强度影响实测 1. 像素艺术生成技术概述 像素幻梦(Pixel Dream Workshop)是基于FLUX.1-dev扩散模型构建的专业像素艺术生成工具。它采用16-bit现代明亮风格设计,为创作者提供…...
PowerBuilder老系统维护指南:PB12.5连接现代数据库(如MySQL 8.0)的避坑实操
PowerBuilder老系统维护实战:PB12.5连接MySQL 8.0的七个关键步骤 当技术栈的代际差异超过十年,每一次数据库连接尝试都可能演变成一场跨越时空的调试马拉松。那些在2006年运行良好的PB12.5应用,今天面对MySQL 8.0的SSL加密要求和UTF8MB4字符集…...
