当前位置: 首页 > 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.lqws.cn/news/574849.html

相关文章:

  • 浅谈AI大模型-MCP
  • 机器学习在智能电网中的应用:负荷预测与能源管理
  • Nginx漏洞处理指南
  • Leetcode 3598. Longest Common Prefix Between Adjacent Strings After Removals
  • 第8篇:Gin错误处理——让你的应用更健壮
  • 【Typst】自定义彩色盒子
  • 【NLP 实战】蒙古语情感分析:从 CNN 架构设计到模型训练的全流程解析(内附项目源码及模型成果)
  • BP-Tools21.02下载 加解密利器 金融安全交易算法工具 PCI认证工具 金融和智能卡的数据加解密和数据转换工具
  • 无人机用shell远程登录机载电脑,每次需要环境配置原因
  • 06_注意力机制
  • (七)集成学习
  • git lfs 提交、拉取大文件
  • 【Linux高级全栈开发】2.4 自研框架:基于 dpdk 的用户态协议栈的实现
  • 华为云Flexus+DeepSeek征文 | 华为云 ModelArts Studio 赋能 AI 法务:合同审查与法律文件生成系统
  • M|艺伎回忆录
  • 从理论到实战:解密大型语言模型的核心技术与应用指南
  • (LeetCode 面试经典 150 题 ) 134. 加油站 (贪心)
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(5):2022年12月2023年7月
  • 通过HTTPS访问Harbor2.13.1 的配置
  • 1.认识Docker
  • #华为鲲鹏#华为计算#鲲鹏开发者计划2025#
  • Prompt Depth Anything:以提示方式驱动的Depth Anything用于实现4K分辨率下的精确米制深度估计
  • 04-GRU模型
  • python中多线程:线程插队方法join详解、线程停止、通过变量来让线程停止
  • Linux中ssh无法使用配置的环境变量,ssh(非登录环境)环境变量和登录环境变量不同步问题
  • document.write 和 innerHTML、innerText 的区别
  • MATLAB仿真:经过大气湍流的涡旋光束的光斑漂移
  • Transformer超详细全解!含代码实战
  • 双指针的用法
  • 指针篇(6)- sizeof和strlen,数组和指针笔试题