cJSON使用教程
最近本人在学习使用cJSON库中的API使用,我根据自身的学习情况,梳理了各个常用API的主要功能,提供给大家学习和参考,有错误的地方欢迎大家指出。cJSON是一个轻量级的,基于C语言实现的,可实现JSON文件解析和生成的开源库。git仓库为:使用该库,仅需要把cJSON.c和cJSON.h两个文件放入到项目中,即可使用。cJSON.ccJSON.hmain.cMakefile目录结构较为简单。
1.前言
最近本人在学习使用cJSON库中的API使用,我根据自身的学习情况,梳理了各个常用API的主要功能,提供给大家学习和参考,有错误的地方欢迎大家指出。
2.库简介
cJSON是一个轻量级的,基于C语言实现的,可实现JSON文件解析和生成的开源库。git仓库为:
https://github.com/DaveGamble/cJSON。使用该库,仅需要把cJSON.c和cJSON.h两个文件放入到项目中,即可使用。

本教程的文件目录主要如下:
- cJSON.c
- cJSON.h
- main.c
- Makefile
目录结构较为简单。其中Makefile文件可自行编写。在main.c中编写如下代码。之后运行make指令,执行main.exe后,若能输出cJSON版本信息,则代表cJSON库移植成功。
main.c代码
#include <stdio.h>
#include "cJSON.h"
int main()
{
const char *version = cJSON_Version();
printf("cJSON version: %s\n", version);
return 0;
}
执行结果
PS C:\Users\17464\Desktop\cjson> .\main.exe
cJSON version: 1.7.19
PS C:\Users\17464\Desktop\cjson>
3. JSON简介
JSON是一种轻量级的数据交换格式,
3.1. 数据类型
| 数据类型 | 示例 |
|---|---|
| 对象 (Object) | 花括号 { }表示一个对象 |
| 数组 (Array) | 方括号 [ ]表示,如 [1, 2, 3] |
| 字符串 (String) | 用双引号表示,如 “hello” |
| 数值(Number) | 1 或 -1 或 3.14 |
| 布尔值 (Boolean) | true 或 false,必须小写 |
| 空值 (Null) | null,必须小写 |
json主要支持以上6种数据类型,基本上满足了各种数据类型的表示。在实际开发中,可根据实际数据类型进行灵活的组合,下面提供一个参考的json数据。
3.2. JSON格式
{
"name" : "mark",
"age" : 22,
"work" : true,
"date" :[2025,10,25],
"girlfriend" : null,
"friends": [
{
"name" : "John",
"age" : 20,
"work" : false,
"address" : ["China","Zhejiang","Hangzhou"]
},
{
"name" : "Jane",
"age" : 23,
"work" : true
}
]
}
通过观察上述示例的数据结构,可以得出以下结论:
- 数组内的元素可以是数字,也可以是字符串。
- 数组内可以嵌套对象。
- 对象内的元素必须满足键值对的格式,即key : value。
- 在对象和数组中,除最后一个数据,都要用逗号“ ,” 隔开。
4. API函数介绍
经过简单的铺垫,下面直接进入主题,开始介绍下cJSON库中各种常用API,我将API主要分成解析、打印、查找、类型判断、创建、添加、修改这几个板块。
4.1. 解析
4.1.1. cJSON_Parse
/**
* @brief 解析JSON字符串,生成一个链表,为后续API提供入参
*
* @param value JSON字符串
* @return cJSON* 返回cJSON链表
*/
(cJSON *) cJSON_Parse(const char *value);
4.2. 打印
4.2.1. cJSON_Print
/**
* @brief 打印cJSON链表为JSON字符串
*
* @param item cJSON链表
* @return char* JSON字符串
*/
(char *) cJSON_Print(const cJSON *item);
4.2.2. cJSON_PrintUnformatted
/**
* @brief 打印cJSON链表为JSON字符串(压缩)
*
* @param item cJSON链表
* @return char* 压缩处理的JSON字符串
*/
(char *) cJSON_PrintUnformatted(const cJSON *item);
4.3. 数据查找
4.3.1. cJSON_GetObjectItem
/**
* @brief 查找指定键,不区分大小写
*
* @param object cJSON链表
* @param string 待查找键名
* @return cJSON* 存储该数据信息的结构体
*/
(cJSON *) cJSON_GetObjectItem(const cJSON * const object,
const char * const string);
4.3.2. cJSON_GetObjectItemCaseSensitive
/**
* @brief 查找指定键,区分大小写
*
* @param object cJSON链表
* @param string 待查找键名
* @return cJSON* 存储该数据信息的结构体
*/
(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object,
const char * const string);
4.4. 数据类型判断
以下接口可以用来判断cJSON * 类型数据属于JSON哪种的数据类型,其接口如下:
| API | 功能 |
|---|---|
| cJSON_IsObject | 检查数据是否为对象 |
| cJSON_IsArray | 检查数据是否为数组 |
| cJSON_IsString | 检查数据是否为字符串 |
| cJSON_IsNumber | 检查数据是否为数值 |
| cJSON_IsBool | 检查数据是否为布尔值 |
| cJSON_IsNull | 检查数据是否为空值 |
这些API的入参都是cJSON *类型,可以用来判断查找API来确定返回的CJSON *为哪种数据类型。
4.5. 数据读取
4.5.1. cJSON_GetStringValue
/**
* @brief 查找指定键的对应字符串值
*
* @param itemc 输入键
* @return char* 对应键的字符串值
*/
(char *) cJSON_GetStringValue(const cJSON * const item)
4.5.2. cJSON_GetNumberValue
/**
* @brief 查找指定键的对应数值
*
* @param itemc 输入键
* @return char* 对应键的数值
*/
(double) cJSON_GetNumberValue(const cJSON * const item)
4.6. 创建数据
| API | 功能 |
|---|---|
| cJSON_CreateObject | 创建对象类型数据 |
| cJSON_CreateArray | 创建数组类型数据 |
| cJSON_CreateString | 创建字符串类型数据 |
| cJSON_CreateNumber | 创建数值类型数据 |
| cJSON_CreateBool | 创建布尔值类型数据 |
| cJSON_CreateNull | 创建空值类型数据 |
4.7. 添加数据
以下是快捷添加的API
| API | 功能 |
|---|---|
| cJSON_AddObjectToObject | 在对象中添加对象类型 |
| cJSON_AddArrayToObject | 在对象中添加数组类型 |
| cJSON_AddStringToObject | 在对象中添加字符串类型 |
| cJSON_AddNumberToObject | 在对象中添加数值类型 |
| cJSON_AddBoolToObject | 在对象中添加布尔值类型 |
| cJSON_AddNullToObject | 在对象中添加空值类型 |
还有一些API是手动添加的,主要是搭配创建数据API,完成数据的创建后,在执行下面的API添加到对象或者数组中。
- cJSON_AddItemToObject()
- cJSON_AddItemToArray()
5. 注意事项
-
cJSON库中通过API返回的char *和cJSON *类型数据都是通过动态内存申请得到,在不需要使用这些数据时,需要释放内存,防止内存碎片化。其中char *类型的数据通过cJSON_free释放。cJSON *类型的数据通过cJSON_Delete释放,并且由于cJSON支持递归删除,只需要删除根节点即可。
-
同时cJSON内存管理的接口,默认使用c标准库的函数,及malloc、free、realloc。若在操作系统中使用cJSON库,建议更换成操作系统提供的内存管理接口。如使用FreeRTOS实时操作系统,需将
internal_malloc这个宏对应的malloc替换成pvPortMalloc。
internal_free这个宏对应的free替换成vPortFree。
6. 应用示例
6.1. JSON读取
以下代码为读取test.json内的信息,并打印json表内容,以及特定键值对。
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
/**
* @brief 从文件读取 JSON 字符串
*
* @param filename 文件路径
* @return char* JSON 字符串(需要调用者 free),失败返回 NULL
*/
char* read_json_file(const char *filename) {
FILE *file = NULL;
char *buffer = NULL;
long file_size = 0;
size_t read_size = 0;
// 打开文件
file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
return NULL;
}
// 获取文件大小
fseek(file, 0, SEEK_END);
file_size = ftell(file);
fseek(file, 0, SEEK_SET);
if (file_size < 0) {
fprintf(stderr, "Error: Cannot determine file size\n");
fclose(file);
return NULL;
}
// 分配内存(+1 用于 '\0')
buffer = (char*)malloc(file_size + 1);
if (buffer == NULL) {
fprintf(stderr, "Error: Memory allocation failed\n");
fclose(file);
return NULL;
}
// 读取文件内容
read_size = fread(buffer, 1, file_size, file);
buffer[read_size] = '\0'; // 添加字符串结束符
fclose(file);
return buffer;
}
int main()
{
/* 读取JSON文件 */
char* json_string = read_json_file("test.json");
/* 解析JSON字符串 */
cJSON *cjson_parse = cJSON_Parse(json_string);
/* 打印JSON字符串 */
char *print_json = cJSON_Print(cjson_parse);
printf("print_json: \n%s\n", print_json);
cJSON_free(print_json);
cJSON *get_name = cJSON_GetObjectItem(cjson_parse,"name");
if(cJSON_IsString(get_name))
{
printf("get_name: %s\n", cJSON_GetStringValue(get_name));
}
cJSON *get_age = cJSON_GetObjectItem(cjson_parse,"age");
if(cJSON_IsNumber(get_age))
{
printf("get_age: %f\n", cJSON_GetNumberValue(get_age));
}
cJSON_Delete(cjson_parse);
return 0;
}
输出
print_json:
{
"name": "mark",
"age": 22,
"work": true,
"date": [2025, 10, 25],
"girlfriend": null,
"friends": [{
"name": "John",
"age": 20,
"work": false,
"address": ["China", "Zhejiang", "Hangzhou"]
}, {
"name": "Jane",
"age": 23,
"work": true
}]
}
get_name: mark
get_age: 22.000000
6.2. JSON生成
以下代码为生成test.json内的信息,并打印生成后的json表内容。
main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "cJSON.h"
int main()
{
/* 创建一个JSON对象 */
cJSON *out_json = cJSON_CreateObject();
/* 添加字符串类型数据 */
cJSON_AddStringToObject(out_json, "name", "mark");
/* 添加数值类型数据 */
cJSON_AddNumberToObject(out_json, "age", 22);
/* 添加布尔类型数据 */
cJSON_AddBoolToObject(out_json, "work", true);
/* 添加数组类型数据 */
cJSON *date_array = cJSON_CreateArray();
/* 添加数组元素 */
cJSON_AddItemToArray(date_array, cJSON_CreateNumber(2025));
cJSON_AddItemToArray(date_array, cJSON_CreateNumber(10));
cJSON_AddItemToArray(date_array, cJSON_CreateNumber(25));
cJSON_AddItemToObject(out_json, "date", date_array);
/* 添加数组类型数据 */
cJSON *friends_array = cJSON_CreateArray();
/* 添加数组元素 */
/* 创建friend1对象 */
cJSON *friend1 = cJSON_CreateObject();
cJSON_AddStringToObject(friend1, "name", "John");
cJSON_AddNumberToObject(friend1, "age", 20);
cJSON_AddBoolToObject(friend1, "work", false);
/* 在数组元素中添加friend1对象 */
cJSON_AddItemToArray(friends_array, friend1);
/* 创建friend2对象 */
cJSON *friend2 = cJSON_CreateObject();
cJSON_AddStringToObject(friend2, "name", "Jane");
cJSON_AddNumberToObject(friend2, "age", 23);
cJSON_AddBoolToObject(friend2, "work", true);
/* 在数组元素中添加friend2对象 */
cJSON_AddItemToArray(friends_array, friend2);
/* 在JSON对象中添加friends数组 */
cJSON_AddItemToObject(out_json, "friends", friends_array);
/* 打印JSON对象 */
char *print1_json = cJSON_Print(out_json);
printf("print1_json: \n%s\n", print1_json);
cJSON_free(print1_json);
/* 压缩打印JSON对象 */
char *print2_json = cJSON_PrintUnformatted(out_json);
printf("print2_json: \n%s\n", print2_json);
cJSON_free(print2_json);
/* 释放内存 */
cJSON_Delete(out_json);
return 0;
}
输出
print1_json:
{
"name": "mark",
"age": 22,
"work": true,
"date": [2025, 10, 25],
"friends": [{
"name": "John",
"age": 20,
"work": false
}, {
"name": "Jane",
"age": 23,
"work": true
}]
}
print2_json:
{"name":"mark","age":22,"work":true,"date":[2025,10,25],"friends":[{"name":"John","age":20,"work":false},{"name":"Jane","age":23,"work":true}]}
PS C:\Users\17464\Desktop\cjson>
7. 总结
cJSON 是一个优秀的基于C语言的开源库,其简洁的API设计具有很高的学习价值。通过本文的学习,相信读者已经掌握了cJSON的基本使用方法。后续笔者将编写更多有价值的内容,希望得到大家的支持。
更多推荐

所有评论(0)