cJSON 处理 JSON(轻量级 C 语言库)(二)
第二部分:cJSON 处理 JSON(轻量级 C 语言库)
📢 快速掌握 cJSON!文章 + 视频双管齐下 🚀
如果你觉得阅读文章太慢,或者更喜欢 边看边学 的方式,不妨直接观看我录制的 cJSON 课程视频!🎬 视频里会用更直观的方式讲解 cJSON 的核心概念、实战技巧,并配有动手演示,让你更高效地掌握 JSON 的处理方法!
当然,如果你喜欢深度阅读,这篇文章会帮助你系统地理解 cJSON,从基础到进阶!无论你选择哪种方式,最终目标都是让你成为 cJSON 处理的高手!💪
🎥 点击这里观看视频 👉 视频链接
一:cJSON 库概述与环境配置
1.1 cJSON 简介(特点、适用场景)
- cJSON 是一个轻量级、开源的 C 语言 JSON 解析库,专门用于处理 JSON 格式数据。它具有以下特点:
- 简单易用,API 设计清晰,代码可读性强。
- 轻量级,适用于嵌入式系统、物联网(IoT)等对资源敏感的应用场景。
- 无需额外依赖,仅需一个
cJSON.c和cJSON.h文件即可使用。
1.2 下载和安装 cJSON
方法 1:直接下载 cJSON 源码
-
从 cJSON 官方 GitHub 下载
cJSON.h和cJSON.c。https://github.com/DaveGamble/cJSON
-
在项目中包含 cJSON.h:
#include "cJSON.h" -
编译时需链接 cJSON.c:
gcc main.c cJSON.c -o main
方法 2:使用 CMake 进行安装
-
克隆 cJSON 源码:
git clone https://github.com/DaveGamble/cJSON.git cd cJSON -
使用 CMake 编译:
mkdir build cd build cmake .. make sudo make install # 头文件 /usr/local/include 或 /usr/include # 库文件 /usr/local/lib 或 /usr/lib # execute /usr/local/bin 或 /usr/bin
1.3 在 C 语言项目中集成 cJSON(CMake / 手动编译)
示例代码:CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(cJSONExample)add_executable(cjson_test main.c cJSON.c)
1.4 cJSON 数据类型
cJSON 提供了多种数据类型来处理不同的 JSON 数据。下面列出所有可用的类型:
| 类型 | 描述 | 示例 |
|---|---|---|
| cJSON_False | 代表 JSON 中的 false | false |
| cJSON_True | 代表 JSON 中的 true | true |
| cJSON_NULL | 代表 JSON 中的 null | null |
| cJSON_Number | 代表 JSON 中的数字 | 123, -45.67 |
| cJSON_String | 代表 JSON 中的字符串 | "Hello, world!" |
| cJSON_Array | 代表 JSON 中的数组 | [1, 2, 3] |
| cJSON_Object | 代表 JSON 中的对象 | {"name": "Alice"} |
| cJSON_Raw | 代表 JSON 中的原始值(不进行转义) | "\\u1234" |
二:使用 cJSON 解析 JSON
- 加载 JSON 数据(字符串)
- 解析 JSON 字符串为 cJSON 对象
- 访问 JSON 对象的键值对
- 遍历 JSON 数组
讲解内容
解析 JSON 字符串
cJSON_Parse()将 JSON 字符串转换为 cJSON 结构体对象。- 访问 JSON 数据(字符串、数值、布尔值、数组、对象)。
2.1 加载 JSON 字符串
-
cJSON 提供了
cJSON_Parse来将 JSON 字符串解析为 cJSON 对象。 -
cJSON_Print来输出,将cJSON item/实体/结构渲染为文本
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main() {// JSON 字符串const char *json_str = "{\"name\":\"Alice\",\"age\":25,\"is_student\":false}";// 解析 JSON 字符串cJSON *json = cJSON_Parse(json_str);if (json == NULL) {printf("解析失败!\n");return -1;}// 打印解析后的 JSON 对象char *printed_json = cJSON_Print(json);printf("解析后的 JSON: %s\n", printed_json);// 释放内存cJSON_Delete(json);free(printed_json);return 0;
}
2.2 解析 JSON 字符串
- 通过
cJSON_GetObjectItem来获取指定键的值,并根据其类型进一步处理。
📌 示例 1:解析一个简单 JSON
{"name": "张三","age": 28,"married": false
}
✅ C 代码解析 JSON
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main() {// JSON 字符串const char *json_str = "{\"name\": \"张三\", \"age\": 28, \"married\": false}";// 解析 JSONcJSON *root = cJSON_Parse(json_str);if (root == NULL) {printf("JSON 解析失败!\n");return -1;}// 读取 name 字段cJSON *name = cJSON_GetObjectItem(root, "name");if (cJSON_IsString(name)) {printf("姓名: %s\n", name->valuestring);}// 读取 age 字段cJSON *age = cJSON_GetObjectItem(root, "age");if (cJSON_IsNumber(age)) {printf("年龄: %d\n", age->valueint);}// 读取 married 字段cJSON *married = cJSON_GetObjectItem(root, "married");if (cJSON_IsBool(married)) {printf("已婚: %s\n", married->valueint ? "是" : "否");}// 释放 JSON 内存cJSON_Delete(root);return 0;
}
✅ 输出结果
姓名: 张三
年龄: 28
已婚: 否
2.3 解析 JSON 数组
📌 示例 2:解析数组
{"fruits": ["苹果", "香蕉", "葡萄"]
}
✅ C 代码解析 JSON 数组
const char *json_str = "{ \"fruits\": [\"苹果\", \"香蕉\", \"葡萄\"] }";
cJSON *root = cJSON_Parse(json_str);
cJSON *fruits = cJSON_GetObjectItem(root, "fruits");if (cJSON_IsArray(fruits)) {int array_size = cJSON_GetArraySize(fruits);for (int i = 0; i < array_size; i++) {cJSON *item = cJSON_GetArrayItem(fruits, i);printf("水果 %d: %s\n", i + 1, item->valuestring);}
}
✅ 输出
水果 1: 苹果
水果 2: 香蕉
水果 3: 葡萄
2.4 解析 JSON 文件
📌 示例 4:读取 JSON 文件
- 创建
config.json:
{"server": "192.168.1.1","port": 8080,"debug": true
}
- C 代码解析 JSON 文件
FILE *file = fopen("config.json", "r");
if (!file) {printf("无法打开文件\n");return -1;
}char buffer[1024];
fread(buffer, 1, sizeof(buffer), file);
fclose(file);cJSON *root = cJSON_Parse(buffer);
printf("服务器: %s\n", cJSON_GetObjectItem(root, "server")->valuestring);
printf("端口: %d\n", cJSON_GetObjectItem(root, "port")->valueint);
printf("调试模式: %s\n", cJSON_GetObjectItem(root, "debug")->valueint ? "开启" : "关闭");cJSON_Delete(root);
✅ 输出
服务器: 192.168.1.1
端口: 8080
调试模式: 开启
重点知识
✅ cJSON_Parse() 解析 JSON
✅ 访问 JSON 数据的方法(对象和数组)
✅ 释放 cJSON 解析后的内存(cJSON_Delete())
学习目标
- 能够使用 cJSON 解析 JSON 字符串。
- 掌握 cJSON 访问 JSON 数据的 API。
- 了解 JSON 解析后如何正确释放内存。
三:创建、修改、删除 JSON数据
- 创建 JSON 对象和数组
- 动态添加/删除键值对
- 修改 JSON 数据
- 格式化 JSON 输出
讲解内容
创建 JSON 对象
cJSON_CreateObject()创建 JSON 对象。cJSON
相关文章:
cJSON 处理 JSON(轻量级 C 语言库)(二)
第二部分:cJSON 处理 JSON(轻量级 C 语言库) 📢 快速掌握 cJSON!文章 + 视频双管齐下 🚀 如果你觉得阅读文章太慢,或者更喜欢 边看边学 的方式,不妨直接观看我录制的 cJSON 课程视频!🎬 视频里会用更直观的方式讲解 cJSON 的核心概念、实战技巧,并配有动手演示…...
服务器数据恢复—误格式化NTFS文件系统分区别慌,NTFS数据复活秘籍
NTFS文件系统下格式化在理论上不会对数据造成太大影响,但有可能造成部分文件目录结构丢失的情况。下面介绍一个人为误操作导致服务器磁盘阵列中的NTFS文件系统分区被格式化后的服务器数据恢复案例。 服务器数据恢复过程: 1、将故障服务器连接到一台备份…...
《Linux运维总结:基于银河麒麟V10+ARM64架构CPU源码编译部署单实例redis7.2.6》
总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:《Linux运维篇:Linux系统运维指南》 一、环境信息 环境信息如下: 主机IP 操作系统 Redis版本 CPU架构 192.168.1.111 K…...
华为云对象存储服务(OBS)
华为云对象存储服务(OBS) 前言 华为云为开发者提供了丰富的 Java SDK,借助这些 SDK 能够方便地与华为云的各类服务进行交互。下面以 华为云对象存储服务(OBS) 的 Java SDK 为例,介绍其使用步骤。 华为云…...
【3】数据结构的双向链表章
目录标题 双向链表的定义双向链表的初始化双向链表的创建插入操作删除操作 双向链表总代码与调试 双向链表的定义 结点结构组成:数据域(data)、指针域(pre)、指针域(next)。其中, da…...
分布式环境下的主从数据同步
目录 1. 数据同步的推/拉方式 1.1 主节点推送 1.2 从节点拉取 1.3 常见组件的推拉方式 2.复制方式 2.1 同步复制 2.2 异步复制 2.3 半同步复制 2.4 常见组件的同步方式 3.日志格式 3.1 基于语句复制 SBR 3.2 基于行复制 RBR 3.3 基于预写日志 WAL 3.4 基于触发器…...
蓝桥杯杯赛-日期模拟
知识点 处理日期 1. 按天枚举日期:逐天遍历起始日期到结束日期范围内的每个日期。 2. 处理闰年:正确判断闰年条件。闰年定义为:年份 满足以下任意一个条件:(闰年的2月只有29天) 满足下面一个条件就是闰年 1> 是 400 的倍数…...
【SQL】MySQL基础2:视图,存储过程,游标,约束,触发器
文章目录 1. 视图2. 存储过程2.1 创建存储过程2.2 执行存储过程 3. 游标4. 约束4.1 主键约束4.2 外键约束4.3 唯一约束4.4 检查约束 5. 触发器 1. 视图 视图是虚拟的表,它是动态检索的部分。使用视图的原因:避免重复的SQL语句;使用表的部分而…...
【TS学习】(15)分布式条件特性
在 TypeScript 中,分布式条件类型(Distributive Conditional Types) 是一种特殊的行为,发生在条件类型作用于裸类型参数(Naked Type Parameter) 时。这种特性使得条件类型可以“分布”到联合类型的每个成员…...
Android 小组件
小部件的布局文件支持如下布局: FrameLayout LinearLayout RelativeLayout GridLayout 以及如下控件 AnalogClock Button Chronometer ImageButton ImageView ProgressBar TextView ViewFlipper ListView GridView StackView AdapterViewFlipper 应该不止这些有空…...
搭建开源笔记平台:outline
折腾的意义 为什么要自己搭建一个笔记平台?没理由,就是突然想试试。有时候突然有个想法,搜了一下正好有合适的方案,就顺手试一下。 其实已经有很多成熟的笔记软件,例如Notion/OneNote,但谁不想要一个数据完…...
Unity编辑器功能及拓展(2) —Gizmos编辑器绘制功能
Unity中的Gizmos功能是用于在场景视图中绘制辅助图形或图标的工具,帮助开发者在编辑模式下直观调试和可视化游戏对象的位置、范围、方向等信息。 一.定义概述 Gizomsd 概述 Gizoms是Unity提供的一个API,或者叫做一个工具类,包含一系列静态…...
电脑屏幕亮度随心控,在Windows上自由调整屏幕亮度的方法
调整电脑屏幕的亮度对于保护视力和适应不同环境光线条件非常重要。无论是在白天强光下还是夜晚昏暗环境中,合适的屏幕亮度都能让您的眼睛更加舒适。本文中简鹿办公小编将向您介绍几种在 Windows 系统中调整屏幕亮度的方法。 方法一:使用快捷键 大多数笔…...
presto行转列
presto的行列转换和spark、hive一样也是通过外链语句实现的,只不过语法和关键子有点不同,如下 with tmp1 as (select 1,2,3 as a1,4,5,6 as a2 ) select * from tmp1 cross join unnest(split(tmp1.a1, ,),split(tmp1.a2, ,) ) as b(a1s,a2s) 结果如下...
MySQL 5.7 Online DDL 技术深度解析
14.13.1 在线DDL操作 索引操作主键操作列操作生成列操作外键操作表操作表空间操作分区操作 索引操作 下表概述了对索引操作的在线DDL支持情况。星号表示有附加信息、例外情况或依赖条件。有关详细信息,请参阅语法和使用说明。 操作原地执行重建表允许并发DML仅修…...
【汽车功能安全:软件与硬件缺一不可】
随着汽车变得越来越智能,功能安全就成为汽车电子系统不可回避的标准体系,日益复杂的功能导致了汽车中电子元件的数量和复杂性的指数级增长(Leen)。如今高级别汽车拥有多达90个电子控制单元(ECU),…...
docker打包使用有头模式playwright
1.打包镜像 创建Dockerfile文件如下 # playywright 官方镜像 FROM mcr.microsoft.com/playwright:v1.37.0-jammy# 设置非交互式环境变量和时区 ENV DEBIAN_FRONTENDnoninteractive ENV TZEtc/UTC# 安装 Python 3.9 和 pip(修复时区阻塞问题) RUN apt-g…...
TCP/IP协议的应用层与传输层
TCP/IP协议簇是互联网的核心通信框架,定义了数据如何在网络中封装、寻址、传输和路由(确定数据包从源主机到目标主机的传输路径的过程)。 应用层 直接面向用户和应用,负责实现网络服务的具体功能(如网页浏览、文件传输…...
51c自动驾驶~合集15
我自己的原文哦~ https://blog.51cto.com/whaosoft/11720657 #DRAMA 首个基于Mamba的端到端运动规划器(新加坡国立) 运动规划是一项具有挑战性的任务,在高度动态和复杂的环境中生成安全可行的轨迹,形成自动驾驶汽车的核心能…...
拼多多 anti-token unidbg 分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向分析 版本7.3-7.4 都试过加密没什…...
【Git】5 个分区的切换方式及示例
目录 1. **工作区(Working Directory)**2. **缓存区(Stage/Index)**3. **本地仓库(Local Repository)**4. **远程仓库(Remote Repository)**5. **贮藏区(Stash࿰…...
Java高频面试之并发编程-02
hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝🐶 面试官:进程和线程的区别是什么? 1. 资源分配与独立性 进程: 独立性:每个进程拥有独立的内存…...
openwebui和keycloak集成,使用keycloak的用户名和密码登录
1,实现效果 使用keycloak定义的用户名和密码,直接登录openwebui 2,实现原理 keycloak中用户信息中包含用户名和密码,以及email。 使用keycloak中的用户名和密码登录之后,会用email创建一个openwebui的账号。之后每次…...
html实现手势密码
<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>手势密码</title><style>body {font-fam…...
【区块链安全 | 第八篇】多签机制及恶意多签
部分参考:慢雾科技 文章目录 为什么需要多签多签机制Tron钱包下的恶意多签Tron 钱包多签权限分类Tron 多签机制的运作方式 恶意多签的过程黑客通过多签机制控制账户黑客剥夺用户权限,完全控制账户 恶意多签成因 在区块链中,多签(M…...
项目如何安装本地tgz包并配置局部registry
一、判断包来源是否正确 1. 检查url curl <registry_url>2. 查看包是否存在 npm view <package_name> --registry<registry_url>二、局部registry配置步骤: 1. 全局配置 如果你希望对所有项目生效,可以将这行配置添加到全局.npmr…...
二月公开赛Web-ssrfme
目录 环境搭建 题目分析 分析代码 解题过程 Redis未授权访问 寻找Flag 环境搭建 进入含有docker-compose.yml的文件内,拉取容器镜像 docker-compose up -d 题目分析 访问容器地址172.25.254.200:8091查看题目 分析代码 url通过GET请求访问界面,…...
JavaRedis和数据库相关面试题
JavaRedis面试题 1. Redis是什么以及Redis为什么快? Redis(Remote Dictionary Server)是一个开源的内存键值数据库,支持多种数据结构(如字符串、哈希、列表、集合等),并提供持久化、复制、…...
告别枯燥工作,走向自动化
嘿,小伙伴们!今天给你们介绍两款超实用的RPA办公自动化软件,用它们,再也不用像机器一样做重复劳动啦,超省时间! 工具名称:影刀RPA(类似产品,八爪鱼 RPA,操作上…...
Spring的 @Conditional @ConditionalOnProperty 注解 笔记250330
Spring的 Conditional ConditionalOnProperty 注解 Spring 的 Conditional 与 ConditionalOnProperty 注解详解 在 Spring 框架中,Conditional 和 ConditionalOnProperty 是用于动态控制 Bean 注册的重要注解。虽然它们都服务于条件化配置,但定位和使用…...
