当前位置: 首页 > news >正文

cJSON 使用方法详解

cJSON 使用方法详解

cJSON 是一个轻量级的 C 语言 JSON 解析器和生成器库,非常适合嵌入式系统和资源受限环境。以下是 cJSON 的详细使用方法。

1. 安装与集成

下载 cJSON

可以直接从 GitHub 获取源码:

git clone https://github.com/DaveGamble/cJSON.git

集成到项目

将 cJSON.h 和 cJSON.c 复制到你的项目中,或者编译为静态库:

cd cJSON
mkdir build
cd build
cmake ..
make
sudo make install  # 安装到系统

2. 基本用法

创建 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); // 0=false, 1=true// 添加数组cJSON *courses = cJSON_CreateArray();cJSON_AddItemToArray(courses, cJSON_CreateString("Math"));cJSON_AddItemToArray(courses, cJSON_CreateString("Physics"));cJSON_AddItemToObject(root, "courses", courses);// 添加嵌套对象cJSON *address = cJSON_CreateObject();cJSON_AddStringToObject(address, "city", "New York");cJSON_AddStringToObject(address, "zip", "10001");cJSON_AddItemToObject(root, "address", address);// 转换为字符串并打印char *json_str = cJSON_Print(root);printf("Generated JSON:\n%s\n", json_str);// 释放内存free(json_str);cJSON_Delete(root);return 0;
}

解析 JSON 字符串

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main() {const char *json_string = "{\"name\":\"Alice\",\"age\":25,\"is_student\":true,\"courses\":[\"Art\",\"History\"]}";// 解析JSON字符串cJSON *root = cJSON_Parse(json_string);if (root == NULL) {const char *error_ptr = cJSON_GetErrorPtr();if (error_ptr != NULL) {fprintf(stderr, "Error before: %s\n", error_ptr);}return 1;}// 获取值cJSON *name = cJSON_GetObjectItemCaseSensitive(root, "name");cJSON *age = cJSON_GetObjectItemCaseSensitive(root, "age");cJSON *is_student = cJSON_GetObjectItemCaseSensitive(root, "is_student");cJSON *courses = cJSON_GetObjectItemCaseSensitive(root, "courses");// 打印值printf("Name: %s\n", name->valuestring);printf("Age: %d\n", age->valueint);printf("Is student: %s\n", cJSON_IsTrue(is_student) ? "true" : "false");// 遍历数组printf("Courses:\n");cJSON *course = NULL;cJSON_ArrayForEach(course, courses) {printf("- %s\n", course->valuestring);}// 释放内存cJSON_Delete(root);return 0;
}

3. 文件读写

写入 JSON 文件

void write_json_file(const char *filename, cJSON *json) {FILE *fp = fopen(filename, "w");if (fp == NULL) {perror("Failed to open file for writing");return;}char *json_str = cJSON_Print(json);fputs(json_str, fp);fclose(fp);free(json_str);
}

读取 JSON 文件

c

cJSON *read_json_file(const char *filename) {FILE *fp = fopen(filename, "r");if (fp == NULL) {perror("Failed to open file for reading");return NULL;}// 获取文件大小fseek(fp, 0, SEEK_END);long length = ftell(fp);fseek(fp, 0, SEEK_SET);// 读取文件内容char *buffer = malloc(length + 1);if (buffer == NULL) {fclose(fp);return NULL;}fread(buffer, 1, length, fp);buffer[length] = '\0';fclose(fp);// 解析JSONcJSON *json = cJSON_Parse(buffer);free(buffer);return json;
}

4. 高级用法

修改现有 JSON

void modify_json(cJSON *root) {// 修改现有值cJSON *age = cJSON_GetObjectItemCaseSensitive(root, "age");if (age != NULL) {age->valueint = 31;}// 添加新字段cJSON_AddStringToObject(root, "email", "john@example.com");// 删除字段cJSON_DeleteItemFromObject(root, "is_student");
}

错误处理

cJSON *parse_json_with_error_handling(const char *json_string) {cJSON *json = cJSON_Parse(json_string);if (json == NULL) {const char *error_ptr = cJSON_GetErrorPtr();if (error_ptr != NULL) {fprintf(stderr, "Error parsing JSON: %s\n", error_ptr);}return NULL;}return json;
}

使用钩子自定义内存管理

c

// 自定义malloc/free函数
static void *custom_malloc(size_t size) {printf("Allocating %zu bytes\n", size);return malloc(size);
}static void custom_free(void *ptr) {printf("Freeing memory at %p\n", ptr);free(ptr);
}void use_custom_allocator() {// 设置自定义内存管理函数cJSON_Hooks hooks;hooks.malloc_fn = custom_malloc;hooks.free_fn = custom_free;cJSON_InitHooks(&hooks);// 现在cJSON会使用自定义的内存管理cJSON *root = cJSON_CreateObject();cJSON_AddStringToObject(root, "test", "value");cJSON_Delete(root);
}

5. 性能优化技巧

  1. 使用缓冲打印

    char buffer[1024];
    cJSON_PrintPreallocated(root, buffer, sizeof(buffer), 0);
  2. 避免频繁分配:重用 cJSON 对象

  3. 使用 cJSON_PrintUnformatted 节省空间:

    char *compact_json = cJSON_PrintUnformatted(root);
  4. 批量操作:减少单独的添加操作

6. 完整示例

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main() {// 1. 创建JSONcJSON *root = cJSON_CreateObject();cJSON_AddStringToObject(root, "name", "John Smith");cJSON_AddNumberToObject(root, "age", 35);cJSON *address = cJSON_CreateObject();cJSON_AddStringToObject(address, "street", "123 Main St");cJSON_AddStringToObject(address, "city", "Boston");cJSON_AddItemToObject(root, "address", address);cJSON *phones = cJSON_CreateArray();cJSON_AddItemToArray(phones, cJSON_CreateString("555-1234"));cJSON_AddItemToArray(phones, cJSON_CreateString("555-5678"));cJSON_AddItemToObject(root, "phones", phones);// 2. 打印JSONchar *json_str = cJSON_Print(root);printf("Generated JSON:\n%s\n", json_str);free(json_str);// 3. 写入文件write_json_file("person.json", root);// 4. 从文件读取并修改cJSON *from_file = read_json_file("person.json");if (from_file != NULL) {cJSON *age = cJSON_GetObjectItemCaseSensitive(from_file, "age");age->valueint += 1;cJSON_AddBoolToObject(from_file, "married", 1);char *modified_json = cJSON_Print(from_file);printf("Modified JSON:\n%s\n", modified_json);free(modified_json);cJSON_Delete(from_file);}// 清理cJSON_Delete(root);return 0;
}

7. 常见问题解决

  1. 内存泄漏

    • 确保为每个 cJSON_Create* 和 cJSON_Print 调用相应的 cJSON_Delete 和 free

  2. 访问不存在的字段

    • 总是检查 cJSON_GetObjectItemCaseSensitive 的返回值是否为 NULL

  3. 类型错误

    • 使用 cJSON_IsStringcJSON_IsNumber 等函数验证类型

  4. 大文件处理

    • 考虑流式解析或分块处理大JSON文件

cJSON 是一个简单但功能强大的库,适用于大多数C语言的JSON处理需求。通过合理的内存管理和错误处理,可以构建健壮的JSON处理代码。

http://www.lryc.cn/news/576850.html

相关文章:

  • 华为云 Flexus+DeepSeek 征文|华为云 Flexus 云服务 Dify-LLM 平台深度部署指南:从基础搭建到高可用实践
  • NLP随机插入
  • 如果将Word里每页的行数设置成50行
  • jenkins启动报错,一直无法启动
  • 高并发电商返利 APP 架构设计:从淘客佣金模型到分布式导购系统的技术落地
  • [分布式并行] 流水线并行 PP(NaivePP/GPipe/F-then-B/PipeDream/1F1B)
  • MySQL数据库的增删改查
  • 茶叶根茎分割数据集介绍与应用
  • RNN人名分类器案例
  • Android大图加载优化:BitmapRegionDecoder深度解析与实战
  • Ubuntu20 编译安装 Redis7.2.4
  • SAP顾问职位汇总(第26周)
  • 大模型岗位面试常见问题及解答
  • python+uniapp基于微信小程序的多人协同办公系统
  • 人工智能之数学基础:如何判断正定矩阵和负定矩阵?
  • chapter02_AbstractBeanfactory与模板方法
  • python sklearn 机器学习(1)
  • Ragflow本地部署和基于知识库的智能问答测试
  • 【Typst】自定义彩色盒子
  • 医疗AI智能基础设施构建:向量数据库矩阵化建设流程分析
  • 如何搭建基于RK3588的边缘服务器集群?支持12个RK3588云手机
  • Qt QGraphics简述及例程 - QGraphicsView、QGraphicsScene和QGraphicsItem
  • 深入剖析Nacos服务发现与注册,及如何基于LoadBalancer实现负载均衡
  • #华为昇腾#华为计算#昇腾开发者计划2025#
  • Redis分布式锁核心原理源码
  • #华为鲲鹏#华为计算#鲲鹏开发者计划2025#
  • Transformer结构与代码实现详解
  • 【电路笔记 TMS320F28335DSP】TI SCI (增强型的UART) 点对点异步串行通信接口
  • 【OpenGL学习】(八)图形变换
  • Oauth2 自定义设置token过期时间