JSON 与 cJSON 学习笔记

1. JSON 是什么?

JSON(JavaScript Object Notation)是一种轻量级文本数据格式,常用于网络传输和配置文件保存。

在物联网中,设备经常把传感器数据组织为 JSON,再通过 MQTT、HTTP 等协议上传,例如:

复制代码
{
  "temp": 25.5,
  "humidity": 60
}

JSON 是纯文本,易读、跨语言,C、Python、JavaScript 等都可以处理。

2. JSON 的两种结构

对象:键值对集合

对象使用 {},键必须是双引号包围的字符串,键和值用 : 分隔:

复制代码
{
  "name": "sensor-01",
  "online": true
}

数组:有序值集合

数组使用 [],元素用逗号分隔:

复制代码
["json", "mqtt", "rt-thread"]

对象和数组可以互相嵌套,用于表达复杂数据。

3. JSON 支持的值类型

类型 示例 注意
字符串 "hello" 必须使用双引号。
数值 42、3.14 不加引号。
布尔值 true、false 必须小写。
空值 null 表示无值。
数组 [1, 2, 3] 有序集合。
对象 {"id": 1} 键值对集合。

4. JSON 语法要点

  • 键必须是双引号包围的字符串,不能写成 {name: "tom"}。

  • 最后一个成员后面不能有逗号。

  • 字符串中需要转义时使用 \"、\\、\n 等。

  • 空格和换行不影响 JSON 含义,可用于提升可读性。

  • JSON 不是 C 结构体,也不能写注释。

错误示例:

复制代码
{
  "temp": 25.5,
}

最后多出的逗号会导致 JSON 解析失败。

5. RT-Thread 中使用 cJSON

cJSON 是一个常用的 C 语言 JSON 库。RT-Thread 已将其制作为软件包,启用后包含头文件即可使用:

复制代码
#include <cJSON.h>

cJSON 的核心操作:

复制代码
解析:cJSON_Parse() → 读取字段 → cJSON_Delete()
编码:创建对象 → 添加字段 → cJSON_Print() → 释放字符串和对象

6. cJSON 解析示例

复制代码
const char *json_text =
    "{\"temp\":25.5,\"humidity\":60,\"online\":true}";
​
cJSON *root = cJSON_Parse(json_text);
if (root != RT_NULL)
{
    cJSON *temp = cJSON_GetObjectItemCaseSensitive(root, "temp");
    cJSON *online = cJSON_GetObjectItemCaseSensitive(root, "online");
​
    if (cJSON_IsNumber(temp) && cJSON_IsBool(online))
    {
        rt_kprintf("temp: %.1f, online: %d\n",
                   temp->valuedouble,
                   cJSON_IsTrue(online));
    }
​
    cJSON_Delete(root);
}

代码解析: cJSON_Parse() 将 JSON 文本转换为内存中的 JSON 树,失败时返回 RT_NULL。cJSON_GetObjectItemCaseSensitive() 按键名获取字段;在访问 valuedouble 前,通过 cJSON_IsNumber() 检查类型,避免字段缺失或类型不匹配导致异常。最后的 cJSON_Delete(root) 必须执行,用于释放整棵 JSON 树。

7. cJSON 编码示例

复制代码
cJSON *root = cJSON_CreateObject();
if (root != RT_NULL)
{
    cJSON_AddNumberToObject(root, "temp", 25.5);
    cJSON_AddNumberToObject(root, "humidity", 60);
    cJSON_AddBoolToObject(root, "online", 1);
​
    char *json_str = cJSON_PrintUnformatted(root);
    if (json_str != RT_NULL)
    {
        rt_kprintf("%s\n", json_str);
        cJSON_free(json_str);
    }
​
    cJSON_Delete(root);
}

代码解析: cJSON_CreateObject() 创建根对象,随后将温度、湿度和在线状态作为键值对加入。cJSON_PrintUnformatted() 生成紧凑 JSON 字符串,适合 MQTT 等网络传输。该字符串由 cJSON 分配,使用后必须调用 cJSON_free();根对象则通过 cJSON_Delete() 释放。两种资源不能混用普通 free() 或遗漏释放。

8. 嵌套对象与数组

复制代码
{
  "device": {
    "id": "sensor-01",
    "status": "online"
  },
  "values": [25.5, 60]
}

读取嵌套数据时,先获取外层对象,再获取内层字段;读取数组时可以用 cJSON_GetArraySize() 获取长度,用 cJSON_GetArrayItem() 按下标访问。

总结

JSON 用对象和数组组织文本数据;cJSON 则帮助 C 语言完成 JSON 的解析与生成。

复制代码
接收 JSON:Parse → 校验字段 → 使用数据 → Delete
发送 JSON:Create → Add → Print → free 字符串 → Delete 对象

掌握这条流程后,就可以将 JSON 与 MQTT 结合,用于 RT-Thread 设备的数据上报和指令解析。

相关推荐
成都蜀味缘餐饮技术培训学校35 分钟前
油炸串串技术培训实战指南,核心食材选购与预处理标准
数据仓库·经验分享·笔记·课程设计·微信公众平台
摇滚侠1 小时前
《大模型应用开发实践:基于 Spring AI+DeepSeek 实现》第 11 章 大模型技术概览 阅读笔记 1
人工智能·笔记·spring
xxwl5852 小时前
区域赛算法模版第八章---贪心(Greedy)
c++·笔记·学习·算法
知产xiao_xin3 小时前
专利立法及修改
经验分享·笔记·知识产权
qq_284274053 小时前
S7-1200 PLC硬件与启保停实训:CPU选型与DC/DC/DC、循环扫描五阶段、博途组态及电动机启停自锁梯形图(含考点)
笔记·学习·自动化·制造
dear_bi_MyOnly4 小时前
栈和队列:从原理到应用全解析
c语言·开发语言·c++·学习·分类
雪芽蓝域zzs4 小时前
json数据转化成interface属性
前端·javascript·json
问心无愧05134 小时前
[GXYCTF2019]Ping Ping Ping
android·笔记
ACP广源盛139246256734 小时前
项目评估记录:4K 远距离视频 Serdes 传输方案调研,GSV5800@ACP参数与工程问题记录
笔记·硬件架构·音视频·视频·国产芯片
遇印记5 小时前
应用层,网络管理
运维·网络·windows·学习·安全