cJSON库使用指南
本文详细介绍了轻量级C语言JSON解析库cJSON的使用方法,包含核心功能解析和完整代码示例
什么是cJSON?
cJSON是一个超轻量级的C语言JSON解析库,具有以下特点:
-
单文件实现:仅需
cJSON.c和cJSON.h两个文件 -
跨平台:支持所有主流操作系统和编译器
-
简单易用:API设计简洁直观
-
内存占用小:非常适合嵌入式系统
-
开源免费:采用MIT许可证
环境配置
获取cJSON库
-
从GitHub克隆仓库:
git clone https://github.com/DaveGamble/cJSON.git
-
将以下文件添加到项目中:
-
cJSON.h -
cJSON.c
包含头文件
#include "cJSON.h"
核心数据结构
cJSON使用单一结构体表示所有JSON类型:
typedef struct cJSON {
struct cJSON *next, *prev; // 链表指针
struct cJSON *child; // 子节点指针
int type; // 数据类型
char *valuestring; // 字符串值
int valueint; // 整数值
double valuedouble; // 浮点数值
char *string; // 键名
} cJSON;
数据类型常量
|
常量 |
值 |
说明 |
|
cJSON_False |
0 |
布尔值false |
|
cJSON_True |
1 |
布尔值true |
|
cJSON_NULL |
2 |
NULL值 |
|
cJSON_Number |
3 |
数值类型 |
|
cJSON_String |
4 |
字符串类型 |
|
cJSON_Array |
5 |
数组类型 |
|
cJSON_Object |
6 |
对象类型 |
|
cJSON_Raw |
7 |
原始JSON(不解析) |
常用API函数
创建JSON
|
函数 |
说明 |
|
|
创建JSON对象 |
|
|
创建JSON数组 |
|
|
创建字符串类型 |
|
|
创建数值类型 |
|
|
创建布尔类型 |
|
|
创建NULL类型 |
添加元素
|
函数 |
说明 |
|
|
向对象添加键值对 |
|
|
向数组添加元素 |
|
|
直接添加字符串键值对 |
|
|
直接添加数值键值对 |
解析JSON
|
函数 |
说明 |
|
|
解析JSON字符串 |
|
|
将cJSON结构转换为JSON字符串 |
|
|
生成无格式的JSON字符串 |
查询数据
|
函数 |
说明 |
|
|
根据键名获取对象中的值 |
|
|
获取数组中指定索引的元素 |
|
|
获取数组大小 |
释放内存
void cJSON_Delete(cJSON *item);
完整示例代码
创建JSON对象
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {
// 创建根对象
cJSON *root = cJSON_CreateObject();
// 添加基本类型
cJSON_AddStringToObject(root, "name", "John Doe");
cJSON_AddNumberToObject(root, "age", 30);
cJSON_AddBoolToObject(root, "is_student", 0);
// 创建嵌套对象
cJSON *address = cJSON_CreateObject();
cJSON_AddStringToObject(address, "street", "123 Main St");
cJSON_AddStringToObject(address, "city", "Anytown");
cJSON_AddItemToObject(root, "address", address);
// 创建数组
cJSON *hobbies = cJSON_CreateArray();
cJSON_AddItemToArray(hobbies, cJSON_CreateString("reading"));
cJSON_AddItemToArray(hobbies, cJSON_CreateString("hiking"));
cJSON_AddItemToArray(hobbies, cJSON_CreateString("gaming"));
cJSON_AddItemToObject(root, "hobbies", hobbies);
// 生成JSON字符串
char *json_str = cJSON_Print(root);
printf("Created JSON:\n%s\n", json_str);
// 清理内存
cJSON_Delete(root);
free(json_str);
return 0;
}
解析JSON字符串
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
void parse_json(const char *json_string) {
// 解析JSON
cJSON *root = cJSON_Parse(json_string);
if (!root) {
printf("Error before: [%s]\n", cJSON_GetErrorPtr());
return;
}
// 获取基本类型
cJSON *name = cJSON_GetObjectItem(root, "name");
cJSON *age = cJSON_GetObjectItem(root, "age");
cJSON *is_student = cJSON_GetObjectItem(root, "is_student");
printf("Name: %s\n", name->valuestring);
printf("Age: %d\n", age->valueint);
printf("Is student: %s\n", is_student->valueint ? "true" : "false");
// 解析嵌套对象
cJSON *address = cJSON_GetObjectItem(root, "address");
cJSON *street = cJSON_GetObjectItem(address, "street");
cJSON *city = cJSON_GetObjectItem(address, "city");
printf("Address: %s, %s\n", street->valuestring, city->valuestring);
// 解析数组
cJSON *hobbies = cJSON_GetObjectItem(root, "hobbies");
int hobby_count = cJSON_GetArraySize(hobbies);
printf("Hobbies (%d):\n", hobby_count);
cJSON *hobby;
cJSON_ArrayForEach(hobby, hobbies) {
printf("- %s\n", hobby->valuestring);
}
// 清理内存
cJSON_Delete(root);
}
int main() {
const char *json_string = "{"
"\"name\": \"John Doe\","
"\"age\": 30,"
"\"is_student\": false,"
"\"address\": {"
"\"street\": \"123 Main St\","
"\"city\": \"Anytown\""
"},"
"\"hobbies\": [\"reading\", \"hiking\", \"gaming\"]"
"}";
parse_json(json_string);
return 0;
}
修改JSON数据
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {
const char *json_string = "{\"name\":\"John Doe\",\"age\":30}";
// 解析JSON
cJSON *root = cJSON_Parse(json_string);
// 修改现有值
cJSON *name = cJSON_GetObjectItem(root, "name");
cJSON_SetValuestring(name, "Jane Smith");
cJSON *age = cJSON_GetObjectItem(root, "age");
age->valueint = 32;
// 添加新字段
cJSON_AddStringToObject(root, "email", "jane@example.com");
// 添加数组
cJSON *skills = cJSON_CreateArray();
cJSON_AddItemToArray(skills, cJSON_CreateString("C/C++"));
cJSON_AddItemToArray(skills, cJSON_CreateString("Python"));
cJSON_AddItemToObject(root, "skills", skills);
// 输出修改后的JSON
char *modified_json = cJSON_Print(root);
printf("Modified JSON:\n%s\n", modified_json);
// 清理内存
cJSON_Delete(root);
free(modified_json);
return 0;
}
使用注意事项
-
内存管理:
-
使用
cJSON_Parse()解析的JSON需要手动调用cJSON_Delete()释放 -
cJSON_Print()生成的字符串需要手动free()
-
-
错误处理:
-
检查
cJSON_Parse()返回值是否为NULL -
使用
cJSON_GetErrorPtr()获取错误位置
-
-
类型安全:
-
访问数据前检查
cJSON对象的type字段 -
不要错误访问字段(如将字符串当数值访问)
-
-
性能考虑:
-
避免在循环中频繁创建/删除小对象
-
对于大JSON文件,考虑使用流式解析器
-
-
浮点数精度:
-
cJSON使用
double存储数值 -
注意浮点数精度问题
-
常见问题解答
Q:如何处理嵌套很深的JSON结构?
A:建议使用递归函数遍历JSON树。cJSON提供了child和next指针,可以遍历整个结构。
Q:cJSON支持Unicode吗?
A:cJSON本身不处理Unicode转换,需要保证输入的UTF-8编码正确。
Q:如何区分整数和浮点数?
A:cJSON将所有数值存储为double,同时提供valueint字段。可以使用cJSON_IsNumber()检查是否为数字,然后根据需求选择使用valueint或valuedouble。
Q:cJSON有大小限制吗?
A:理论上只受内存限制,但极大文件可能导致解析缓慢或内存不足。
总结
cJSON是一个功能完备、轻量级的C语言JSON解析库,特别适合资源受限的环境。通过本文的学习,您应该能够:
-
在项目中集成cJSON库
-
创建和解析JSON数据
-
修改和操作JSON结构
-
避免常见的内存管理错误
-
处理复杂的JSON数据结构
cJSON的简洁设计使其成为C/C++项目中处理JSON数据的理想选择。无论是配置文件解析、网络通信还是数据存储,cJSON都能提供高效可靠的解决方案。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐

所有评论(0)