cJSON读取

什么是cJSON?
cJSON是一个轻量级的C语言JSON解析库,由Dave Gamble开发,这个库主要用于将JSON格式的数据转换为C语言中的结构体,方便开发者对数据进行操作,cJSON具有简单、高效的特点,非常适合在嵌入式系统和资源受限的环境中使用。
为什么选择cJSON?
1、轻量级:cJSON的源码非常简洁,只有一个C文件和一个头文件,编译后的文件大小也非常小。
2、高效:解析速度快,占用内存少,适合在性能要求较高的场景中使用。
3、易用性:API设计简单直观,易于上手和使用。
4、跨平台:支持多种操作系统和编译器,具有良好的移植性。
cJSON的核心结构
cJSON的核心结构是cJSON结构体,定义如下:
typedef struct cJSON {
struct cJSON *next,*prev; /* 遍历数组或对象链的前向或后向链表指针 */
struct cJSON *child; /* 数组或对象的孩子节点 */
int type; /* key的类型 */
char *valuestring; /* 字符串值 */
int valueint; /* 整数值 */
double valuedouble; /* 浮点数值 */
char *string; /* key的名字 */
} cJSON;主要功能和接口
1、解析JSON字符串:cJSON *cJSON_Parse(const char *value);
2、获取对象项:cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);

3、获取数组项:cJSON *cJSON_GetArrayItem(cJSON *array, int index);
4、创建JSON对象:cJSON *cJSON_CreateObject();
5、创建JSON数组:cJSON *cJSON_CreateArray();
6、添加元素到对象:void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
7、添加元素到数组:void cJSON_AddItemToArray(cJSON *array, cJSON *item);
8、删除cJSON对象:void cJSON_Delete(cJSON *c);
9、打印未格式化的JSON字符串:char *cJSON_PrintUnformatted(cJSON *c);
10、打印格式化的JSON字符串:char *cJSON_Print(cJSON *c);

示例代码
以下是一个简单的示例,演示如何使用cJSON库读取和解析一个JSON文件:
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
// 读取json文件内容
void read_json() {
FILE *fp = NULL;
long len = 0;
char *data = NULL;
char filename[20] = "data.json";
// 打开文件
fp = fopen(filename, "r");
if (NULL == fp) {
printf("%s don't exist
", filename);
return;
}
// 指针移到文件末尾
fseek(fp, 0, SEEK_END);
// 计算文件长度
len = ftell(fp);
// 指针回到文件开头
fseek(fp, 0, SEEK_SET);
// 申请堆内存
data = (char *)malloc(len + 1);
// 把文件的内容读入data
fread(data, 1, len, fp);
// 关闭文件指针
fclose(fp);
// 定义cJSON指针 root
cJSON *root = NULL;
// 解析数据
root = cJSON_Parse(data);
if (!root) {
printf("Error before: [%s]
", cJSON_GetErrorPtr());
} else {
// 返回数组中的项数
int root_array_size = cJSON_GetArraySize(root);
printf("root_array_size:%d
", root_array_size);
// 从对象获取项“admin”
cJSON *json1 = cJSON_GetObjectItem(root, "admin");
cJSON *json2 = cJSON_GetObjectItem(json1, "username");
printf("username:%s
", json2->valuestring);
json2 = cJSON_GetObjectItem(json1, "type");
printf("type:%d
", json2->valueint);
json2 = cJSON_GetObjectItem(root, "user");
int json2_array_size = cJSON_GetArraySize(json2);
int i = 0, j = 0;
cJSON *item = NULL, *temp1 = NULL, *temp2 = NULL, *temp3 = NULL, *temp4 = NULL;
char *ptr = NULL;
int array_size = 0;
for (i = 0; i < json2_array_size; i++) {
// 从数组“array”中检索项目编号“item”,如果不成功,则返回NULL。
item = cJSON_GetArrayItem(json2, i);
if (!item) {
//TODO...
}
// 将cJSON实体呈现为文本,以便传输/存储,而无需任何格式,完成后释放char*。
ptr = cJSON_PrintUnformatted(item);
temp1 = cJSON_Parse(ptr);
if (!temp1)
continue;
temp2 = cJSON_GetObjectItem(temp1, "username");
printf("username:%s
", temp2->valuestring);
temp3 = cJSON_GetObjectItem(temp1, "other");
array_size = cJSON_GetArraySize(temp3);
for (j = 0; j < array_size; j++) {
temp4 = cJSON_GetArrayItem(temp3, j);
printf("other[%d]:%d
", j, temp4->valueint);
// int num[2] = {0, 1};
// ...
}
}
}
free(data); // 释放内存
cJSON_Delete(root); // 释放cJSON对象
}常见问题与解答(FAQs)
Q1: cJSON如何解析嵌套的JSON对象?
A1: cJSON通过递归的方式解析嵌套的JSON对象,可以使用cJSON_GetObjectItem函数逐层获取嵌套的对象或数组,然后继续解析,如果有一个JSON对象{"admin": {"username": "admin"}},可以先使用cJSON_GetObjectItem获取admin对象,然后再从admin对象中获取username的值。
Q2: 如果cJSON解析失败,如何处理?
A2: 如果cJSON解析失败,会返回NULL并设置错误信息,可以使用cJSON_GetErrorPtr函数获取错误信息,并根据错误信息进行相应的处理,如果文件不存在或者格式不正确,可以提示用户检查文件路径或文件内容。
小伙伴们,上文介绍了“cjson读取”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。