JSON
JSON(Java Script Object Notation,JavaScript对象表示法)
这里不做详细介绍,请参考JSON学习笔记
示例:
{
"message" : "This is JSON",
"group" : ["A", "B", "C"]
}
cJSON
cJSON是一个使用 C 语言编写的JSON数据解析器,具有超轻便,可移植,单位件的特点,使用MIT开源协议。
cJSON数据结构
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
int type;
char *valuestring;
int valueint;
double valuedouble;
char *string;
}cJSON;
抽象出其中一条JSON数据,也就是一个键值对。
用来存放值的成员列表:
string
:用于表示该键的名称;type
:用于表示该键值对中值的类型;valuestring
: 类型(type)是字符串的值;valueint
:类型(type)是整型的值;valuedouble
:类型(type)是浮点型的值。
使用链表来存储整段JSON数据:
next
指针:指向下一个键值对;prev
指针:指向上一个键值对。
因为JSON数据支持嵌套,所以一个键值对的值会是一个新的JSON数据对象(一条新的链表),也有可能是一个数组,在cJSON中,数组也表示为一个数组对象,用链表存储:
child
指针:指向新链表(一个嵌套的JSON数组或一个数组)。
数据封装
实例:
{
"name": "李四",
"age": 16,
"address": {
"country": "China",
"province": "HeNan"
},
"skill": ["C/C++", "Java", "Python"],
"student": false
}
创建实例:
#include <stdio.h>
#include "cJSON.h"
int main(void)
{
cJSON *json_root = NULL;
cJSON *json_address = NULL;
cJSON *json_skill = NULL;
/* 创建一个空表 */
json_root = cJSON_CreateObject();
/* 添加一个字符串的JSON数据 */
cJSON_AddStringToObject(json_root, "name", "李四");
/* 添加一个整型数据 */
cJSON_AddNumberToObject(json_root, "age", 16);
/* 添加一个嵌套JSON数据(子串) */
json_address = cJSON_CreateObjectToObject();
cJSON_AddStringToObejct(json_address, "country", "China");
cJSON_AddStringToObject(json_address, "province", "HeNan");
cJSON_AddObjectToObject(json_root, "address", json_address);
/* 添加一个数组 */
json_skill = cJSON_CreateArrayToObject();
cJSON_AddItemToArray(json_skill, cJSON_CreateString("C/C++"));
cJSON_AddItemToArray(json_skill, cJSON_CreateString("Java"));
cJSON_AddItemToArray(json_skill, cJSON_CreateString("Python"));
/* 添加一个布尔数据 */
cJSON_AddFalseToObject(json_root, "student");
/* 打印数据 */
char *str = cJSON_Print(json_root);
print("%s\n", str);
return 0;
}
数据解析
以上例作为解析数据源
cJSON *json_root = NULL;
json_root = cJSON_Parse(message); //message为上例json数据
if(json_root == NULL) {
printf("parse fail.\n");
}
cJSON *json_name = cJSON_GetObjectItem(json_root, "name");
cJSON *json_age = cJSON_GetObjectItem(json_root, "age");
printf("name: %s\n", json_name->valuestring);
printf("age: %d\n", json_age->valueint);
cJSON *json_address = cJSON_GetObjectItem(json_root, "address");
cJSON *json_address_country = cJSON_GetObjectItem(json_root, "country");
cJSON *json_address_province = cJSON_GetObjectItem(json_root, "province");
printf("address-country: %s\naddress-province: %s\n", json_address_country->valuestring, json_address_province->valuestring);
cJSON *json_skill = cJSON_GetObjectItem(json_root, "skill");
int skill_array_size = cJSON_GetArraySize(json_skill);
for(int i=0; i<skill_array_size; i++)
{
cJSON *json_skill_item = cJSON_GetArrayItem(json_skill, i);
printf("%s, ", json_skill_item->valuestring);
}
printf("\b]\n");
cJSON *json_student = cJSON_GetObjectItem(json_root, "student");
if(json_student->valueint == 0) {
printf("student: false\n");
} else {
printf("student: error\n");
}
cJSON使用过程中的内存问题
cJSON在使用过程中大量的使用malloc
从堆栈中分配内存,所以在使用完之后,应当及时调用下面的函数,清空cJSON指针所指向的内存。
(void) cJSON_Delete(cJSON *item);