在C语言中如何制作JSON数据
在C语言中处理JSON数据(如构建、解析、序列化)是一个常见需求,尤其在嵌入式系统、后端服务或与前端交互的场景中,由于C语言本身没有内置的JSON支持,我们需要借助第三方库来实现,本文将以cJSON这一轻量级、广泛使用的开源库为例,详细介绍如何在C语言中制作JSON数据,包括环境搭建、核心API使用、实战代码示例及注意事项。
环境搭建:安装cJSON库
cJSON是一个用C语言编写的JSON解析器/生成器,具有轻量(仅两个文件:cJSON.h和cJSON.c)、无依赖、跨平台的特点,适合C语言项目。
获取源码
- 从GitHub仓库下载最新版本:
https://github.com/DaveGamble/cJSON.git
或直接下载单个文件:cJSON.h(头文件)和cJSON.c(源文件)。
集成到项目
将cJSON.h和cJSON.c添加到你的C语言项目中,如果是命令行编译,链接时需包含cJSON.c:
gcc your_program.c cJSON.c -o your_program -lm
(-lm是链接数学库,部分版本可能需要)
cJSON核心概念:JSON与cJSON对象的映射
JSON数据本质上是“键值对”的嵌套结构,cJSON通过cJSON对象(对应JSON对象/字典)和cJSON数组(对应JSON数组)来表示,常见类型映射如下:
| JSON类型 | cJSON类型 | 说明 |
|---|---|---|
| 对象 | cJSON*(对象) |
通过cJSON_CreateObject()创建 |
数组 [] |
cJSON*(数组) |
通过cJSON_CreateArray()创建 |
| 字符串 | cJSON*(字符串) |
通过cJSON_CreateString()创建 |
| 数字(整数/浮点) | cJSON*(数字/浮点数) |
通过cJSON_CreateNumber()创建 |
布尔值 true/false |
cJSON*(布尔) |
通过cJSON_CreateTrue()/cJSON_CreateFalse()创建 |
| null | cJSON*(null) |
通过cJSON_CreateNull()创建 |
实战:分步制作JSON数据
假设我们要构建以下JSON对象(用户信息):
{
"name": "张三",
"age": 25,
"isStudent": false,
"courses": ["数学", "英语", "编程"],
"address": {
"city": "北京",
"district": "海淀区"
},
"score": 85.5
}
步骤1:包含头文件并创建根对象
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {
// 1. 创建JSON对象(作为根节点)
cJSON *root = cJSON_CreateObject();
if (!root) {
printf("创建JSON对象失败!\n");
return -1;
}
// 后续操作中,所有cJSON对象都通过root递归构建
}
步骤2:添加键值对(字符串、数字、布尔值)
- 添加字符串:
name->"张三"cJSON_AddStringToObject(root, "name", "张三");
- 添加整数:
age->25cJSON_AddNumberToObject(root, "age", 25);
- 添加布尔值:
isStudent->falsecJSON_AddBoolToObject(root, "isStudent", cJSON_False);
步骤3:添加数组(courses)
- 创建数组对象:
cJSON *courses = cJSON_CreateArray(); if (!courses) { printf("创建数组失败!\n"); cJSON_Delete(root); return -1; } - 向数组中添加字符串元素:
cJSON_AddItemToArray(courses, cJSON_CreateString("数学")); cJSON_AddItemToArray(courses, cJSON_CreateString("英语")); cJSON_AddItemToArray(courses, cJSON_CreateString("编程")); - 将数组添加到根对象:
cJSON_AddItemToObject(root, "courses", courses);
步骤4:添加嵌套对象(address)
- 创建嵌套对象:
cJSON *address = cJSON_CreateObject(); if (!address) { printf("创建嵌套对象失败!\n"); cJSON_Delete(root); return -1; } - 添加嵌套键值对:
cJSON_AddStringToObject(address, "city", "北京"); cJSON_AddStringToObject(address, "district", "海淀区");
- 将嵌套对象添加到根对象:
cJSON_AddItemToObject(root, "address", address);
步骤5:添加浮点数(score)
cJSON_AddNumberToObject(root, "score", 85.5);
步骤6:序列化JSON为字符串
构建完成后,需要将cJSON对象转换为字符串格式,以便存储或传输:
char *json_str = cJSON_Print(root);
if (json_str) {
printf("生成的JSON字符串:\n%s\n", json_str);
free(json_str); // 注意:cJSON_Print返回的字符串需要手动释放
}
步骤7:释放内存
cJSON对象是动态分配的,使用后必须手动释放,避免内存泄漏:
cJSON_Delete(root); // 递归释放所有子对象
完整代码
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {
// 1. 创建根对象
cJSON *root = cJSON_CreateObject();
if (!root) {
printf("创建JSON对象失败!\n");
return -1;
}
// 2. 添加基本键值对
cJSON_AddStringToObject(root, "name", "张三");
cJSON_AddNumberToObject(root, "age", 25);
cJSON_AddBoolToObject(root, "isStudent", cJSON_False);
// 3. 添加数组(courses)
cJSON *courses = cJSON_CreateArray();
cJSON_AddItemToArray(courses, cJSON_CreateString("数学"));
cJSON_AddItemToArray(courses, cJSON_CreateString("英语"));
cJSON_AddItemToArray(courses, cJSON_CreateString("编程"));
cJSON_AddItemToObject(root, "courses", courses);
// 4. 添加嵌套对象(address)
cJSON *address = cJSON_CreateObject();
cJSON_AddStringToObject(address, "city", "北京");
cJSON_AddStringToObject(address, "district", "海淀区");
cJSON_AddItemToObject(root, "address", address);
// 5. 添加浮点数
cJSON_AddNumberToObject(root, "score", 85.5);
// 6. 序列化为字符串
char *json_str = cJSON_Print(root);
if (json_str) {
printf("生成的JSON字符串:\n%s\n", json_str);
free(json_str);
}
// 7. 释放内存
cJSON_Delete(root);
return 0;
}
输出结果
{
"name": "张三",
"age": 25,
"isStudent": false,
"courses": [ "数学", "英语", "编程" ],
"address": {
"city": "北京",
"district": "海淀区"
},
"score": 85.5
}
进阶操作:格式化与错误处理
格式化输出(缩进美化)
默认的cJSON_Print输出无缩进,可使用cJSON_PrintPreallocated(需预分配缓冲区)或cJSON_PrintBuffered(自动管理缓冲区)实现格式化:
char *formatted_json = cJSON_Print(root);
if (formatted_json) {
printf("格式化后的JSON:\n%s\n", formatted_json);
free(formatted_json);
}
错误处理
cJSON通过cJSON_GetErrorPtr()获取错误位置(需开启CJSON_TRACK_ERROR_POINTER宏):
// 在cJSON.h中定义:#define CJSON_TRACK_ERROR_POINTER 1
cJSON *item = cJSON_Parse("invalid json");
if (!item) {
printf("JSON解析失败:%s\n", cJSON_GetErrorPtr());
}
修改JSON数据
- 修改键值:直接调用
cJSON_AddXXXToObject覆盖同名键:
抖音足球直播
抖音足球直播
企鹅直播
企鹅直播
足球直播
爱奇艺直播
爱奇艺足球直播
足球直播
足球直播
iqiyi直播
足球直播
足球直播
QQ足球直播
QQ足球直播
足球直播
足球直播
QQ足球直播
QQ足球直播
足球直播
足球直播
快连
快连
快连
快连下载
快连
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
新浪足球直播
新浪足球直播
足球直播
足球直播
有道翻译
有道翻译
有道翻译
有道翻译
wps
wps
wps
wps
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
新浪足球直播
新浪足球直播
足球直播
足球直播



还没有评论,来说两句吧...