cJSON最小指南
介绍
是一个开源的、精简的、可移植的json解析库,使用C语言编写而成,比较受嵌入式开发者的青睐
数据结构
平行节点看:cJSON是一个双向链表的数据结构,next和prev分别指向当前节点的下一个节点和上一个节点,不存在的节点为NULL
父子节点看:cJSON是一个树目录的数据结构,child指向子节点
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
文件读取
const char *file = "demo.json";
FILE* fp = fopen(file, "rb");
char* data = NULL;
if (fp != NULL)
{
fseek(fp, 0, SEEK_SET);
long begin = ftell(fp);
fseek(fp, 0, SEEK_END);
long end = ftell(fp);
long file_size = end - begin;
fseek(fp, 0, SEEK_SET);
char* data = (char*)malloc(file_size);
while (fread(data, 1, file_size, fp) == 1);
}
对象解析
cJSON* root = cJSON_Parse(data);
if(!root)
{
printf("invalid json object\n");
}
对象打印
printf("%s\n", cJSON_Print(root));
字段解析
子对象
cJSON* channels = cJSON_GetObjectItem(root, "module");
数组对象
#define COUNT 10
int channel_array[COUNT];
if (cJSON_IsArray(channels))
{
printf("channels :\n%s\n\n", cJSON_Print(channels));
int channelSize = cJSON_GetArraySize(channels);
if (COUNT == channelSize)
{
for (int i = 0; i < channelSize; i++)
{
channel_array[i] = cJSON_GetArrayItem(channels, i)->valueint;
}
}
}
整型数值
cJSON* filter = cJSON_GetObjectItem(root, "filter");
printf("filter : %d\n", filter->valueint);
浮点型数值
cJSON* temperature = cJSON_GetObjectItem(root, "temperature");
printf("temperature : %d\n", filter->valuedouble);
对象构造
构造节点
cJSON* system_node = cJSON_CreateObject();
cJSON* json = cJSON_CreateObject();
添加成员
下面示例展示如何添加数值型成员、数组型成员、字符串型成员到json对象
int temp = 0;
int humi = 0;
SHT4xA_get_rht(0xFD, &temp, &humi);
cJSON_AddNumberToObject(system_node, "temperature", temp / 1000.0); // 添加数值型成员
cJSON_AddNumberToObject(system_node, "humidity", humi / 1000.0); // 添加数值型成员
cJSON_AddItemToObject(json, "environment", system_node); // 添加节点型成员
cJSON* voltage_max = cJSON_CreateArray();
{
int voltage;
int ret;
for(int pd = 0; pd < 5; pd++)
{
cJSON_AddItemToArray(voltage_max, cJSON_CreateNumber(100)); // 添加数值型成员到数组
}
cJSON_AddItemToObject(json, "voltage_max", voltage_max); // 添加数组到json对象
}
cJSON_AddStringToObject(json, "alarm_code", "voltage too high"); // 添加字符串型成员到json对象
根节点对象需要删除,文件buffer需要释放,文件句柄需要关闭
if (root)
{
cJSON_Delete(root); // 根节点会遍历所有子节点,释放内存
free(data); // 是否文件buffer
fclose(fp); // 关闭文件句柄
}
注意事项
Windows平台换行符为CR LF
,而Unix平台换行符为LF
,在Windows平台用cJSON库解析json文件会出现识别不了的问题,需要将json文件转成Unix换行符才能正确识别
接口
序号 | 原型 | 用法 |
---|---|---|
1 | cJSON_bool cJSON_IsBool(const cJSON * const item) | 判断item是否Bool类型 |
2 | cJSON_bool cJSON_IsNull(const cJSON * const item) | 判断item是否空指针 |
3 | cJSON_bool cJSON_IsNumber(const cJSON * const item) | 判断item是否数值类型 |
4 | cJSON_bool cJSON_IsString(const cJSON * const item) | 判断item是否字符串 |
5 | cJSON_bool cJSON_IsArray(const cJSON * const item) | 判断item是否数组 |
6 | cJSON_bool cJSON_IsObject(const cJSON * const item) | 判断item是否json对象 |
7 | cJSON* cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) | 添加布尔型成员到object对象 |
8 | cJSON* cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) | 添加数值成员到object对象 |
9 | cJSON* cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) | 添加字符串成员到object对象 |
10 | cJSON* cJSON_AddObjectToObject(cJSON * const object, const char * const name) | 添加空json成员到object对象 |
版本号
打印cJSON版本号
printf("Json Version : %d.%d.%d\n", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
阅读剩余
版权声明:
作者:hywing
链接:https://iotstuff.cn/cjson-guide/
文章版权归作者所有,未经允许请勿转载。
THE END