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" 必须使用双引号。
数值 423.14 不加引号。
布尔值 truefalse 必须小写。
空值 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_NULLcJSON_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 设备的数据上报和指令解析。

相关推荐
一米阳光86612 小时前
软考(中级)软件设计师核心笔记(8)数据结构——树与二叉树
数据结构·笔记·职场发展·软考·软件设计师·中级职称
lifallen2 小时前
Orca 与 Emdash:同样管理多个 Agent,差别在谁来调度
人工智能·学习·ai·软件构建·开源软件·ai编程
runafterhit2 小时前
【学习地图】ARM嵌入式类 · 文章索引
arm开发·学习
沐-风_2 小时前
双通道LVDS(Dual‑Link)Link0 / Link1:硬件、软件、标准
嵌入式硬件·学习
大家的林语冰2 小时前
👍 JS 还在进化,ES2026 正式推出,最新七大特性补全!
前端·javascript·json
是上好佳佳佳呀3 小时前
【深度学习|DAY04】神经网络深度学习笔记(下):损失函数、优化器与正则化
笔记·深度学习·神经网络
风吹心凉4 小时前
ROS2核心概念
学习
秋田君4 小时前
QT_JSON文件操作
开发语言·qt·json
砚凝霜5 小时前
软考网络工程师|第 9 章 网络诊断命令 + 故障工具 + 故障排查完整笔记
网络·笔记