文章目录
- 写在前面
- 一、安装cJSON
- 二、使用cJSON
- 1、使用的文件
- 2、如何传输数据:****
- 三、JSON语法
- 四、cJSON函数讲解
- 1、cJSON结构体 **
- 2、cJSON结构体与字符串之间的转换(重要)
- 2.1、标题将cJSON结构体转换为字符串(常用)
- 2.2、将字符串转为cJSON结构体(常用)
- 3、cJSON创建键值对
- 3.1、先调用 cJSON_CreateXXX 创建对象或数组,然后调用 cJSON_AddItemToObject 将值加入到对象或数组中
- 3.2、直接调用 cJSON_AddXXXToObject 创建并添加值到对象中
- 4、解析
- 5、释放cJSON数据
- 五、示例
- 1、创建
- 2、解析(主要参考与使用)
- 2.1、解析 {}
- 2.2、解析[ {} {} ]
- 3、解析(参考形式)
- 3.1、解析 {}
- 3.2、解析 [ ]
- 3.3、解析 [ {} {} ]
- 3.4、解析[ [ ] [ ] ]
- 3.5、解析 { { } { } }
- 参考文章
写在前面
什么是JSON:一种轻量级的数据交换格式
JSON用途:解析收到的数据和发送对方能够解析的数据
什么是cJSON:c语言格式下使用JSON的工具
一、安装cJSON
cjson官方库,直接点击下载zip,解压缩
git clone https://github.com/DaveGamble/cJSON.git
cd cJSON/
mkdir build
cd build/
cmake ..
make
make install
二、使用cJSON
1、使用的文件
然后我们,可以看到很多文件,但是,我们不需要这么多,使用cjson只需要两个文件,
拷贝cJSON.c和cJSON.h文件到自己的项目中就可以了,linux,windows上都可以使用
CJOSN.h
CJSON.c
2、如何传输数据:****
1、创建cJSON格式数据,转换成为cJSON字符串,然后传输。
2、将cJSON字符串解析成cJSON格式数据,然后提取出相应的数据内容。
三、JSON语法
JSON对象是一个无序的"key(关键字)/value(值)"键值对的集合:
以 "{“开始,以”}“结束 ,允许嵌套使用
每个key(关键字)和value(值)成对出现,关键字和值之间使用”:“分隔
键/值对之间用”,"分隔
在这些字符前后允许存在无意义的空白符
其中**关键字**只能是字符串(使用双引号“”表示)**值**可以有如下表示:数字(整数或浮点数)字符串(在双引号中)逻辑值(true 或 false)数组 (在中括号中)对象 (在大括号中)null
四、cJSON函数讲解
1、cJSON结构体 **
/* The cJSON structure: */
typedef struct cJSON
{
//这些不用管struct cJSON *next;struct cJSON *prev;struct cJSON *child;//这些都要知道//该json对象的类型,可以是字符串,int,double....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,那么值存在这里int valueint;/* The item's number, if type==cJSON_Number *///如果类型是double,那么值存在这里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;
2、cJSON结构体与字符串之间的转换(重要)
2.1、标题将cJSON结构体转换为字符串(常用)
使用这个两个函数一定一定一定要 调用cJSON_Delete函数 释放它们返回的指针内存。
//将CJSON数据转换为字符串(保留原来的格式:例如会保留空格和回车)
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
//将CJSON数据转换为字符串(删除所有格式,只保留文本)
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
2.2、将字符串转为cJSON结构体(常用)
//将json字符串转换为结构体,并且将其赋给一个指针
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
3、cJSON创建键值对
3.1、先调用 cJSON_CreateXXX 创建对象或数组,然后调用 cJSON_AddItemToObject 将值加入到对象或数组中
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); //创建对象---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); //创建数组---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);//创建整型数组
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);//创建双浮点型数组CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); //在对象中添加项目
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);//在数组中添加项目
3.2、直接调用 cJSON_AddXXXToObject 创建并添加值到对象中
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
4、解析
注意:解析—是从cJSON结构体类型中—解析
//获取数组大小
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
//获取数组里面的某一个值
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
//这个函数将某一个键值对,提取出来放到一个结构体中
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
5、释放cJSON数据
void cJSON_Delete(cJSON *c);
/*作用:释放位于堆中cJSON结构体内存
五、示例
1、创建
#include <stdio.h>
#include "cJSON.h"int main(void)
{double grade[4]={66.51,118.52,61.53,128.54};int time[4]={123,456,789,150};cJSON *TCP = cJSON_CreateObject(); //创建一个对象cJSON_AddStringToObject(TCP,"name","MQ"); //添加字符串 cJSON_AddNumberToObject(TCP,"age",25); //添加整型数字 cJSON_AddNumberToObject(TCP,"height",183.52); //添加浮点型数字cJSON_AddFalseToObject(TCP,"gender"); //添加逻辑值falsecJSON *ADD = cJSON_CreateObject(); //创建一个对象cJSON_AddStringToObject(ADD,"country","China"); //添加字符串 cJSON_AddNumberToObject(ADD,"zip-code",123456); //添加整型数字cJSON_AddItemToObject(TCP,"address",ADD);cJSON *SUB = cJSON_CreateArray(); //创建一个数组cJSON_AddStringToObject(SUB,"","政治"); //添加字符串到数组cJSON_AddStringToObject(SUB,"","数学");cJSON_AddStringToObject(SUB,"","英语");cJSON_AddStringToObject(SUB,"","专业课");cJSON_AddItemToObject(TCP,"subject",SUB); //添加数组到对象cJSON *TIM = cJSON_CreateIntArray(time,4); //创建一个整型数组cJSON_AddItemToObject(TCP,"time",TIM);cJSON *GRA = cJSON_CreateDoubleArray(grade,4); //创建一个双浮点型数组cJSON_AddItemToObject(TCP,"grade",GRA);cJSON *STU = cJSON_CreateArray(); //创建一个数组cJSON *Z3 = cJSON_CreateObject(); //创建一个对象cJSON_AddStringToObject(Z3,"name","张三"); //添加字符串 cJSON_AddNumberToObject(Z3,"age",24); //添加整型数字 cJSON_AddTrueToObject(Z3,"gender"); //添加逻辑值 cJSON_AddItemToArray(STU,Z3); //添加对象到数组中 cJSON *L4 = cJSON_CreateObject(); //创建一个对象cJSON_AddStringToObject(L4,"name","李四"); //添加字符串 cJSON_AddNumberToObject(L4,"age",25); //添加整型数字 cJSON_AddTrueToObject(L4,"gender"); //添加逻辑值 cJSON_AddItemToArray(STU,L4); //添加对象到数组中cJSON *W5 = cJSON_CreateObject(); //创建一个对象cJSON_AddStringToObject(W5,"name","王五"); //添加字符串 cJSON_AddNumberToObject(W5,"age",26); //添加整型数字 cJSON_AddTrueToObject(W5,"gender"); //添加逻辑值 cJSON_AddItemToArray(STU,W5); //添加对象到数组中cJSON_AddItemToObject(TCP,"student",STU); //添加数组到对象中char *json_data = cJSON_Print(TCP); //JSON数据结构转换为JSON字符串printf("%s\n",json_data);//输出字符串cJSON_Delete(TCP);//清除结构体return 0;
}
现象
{"name": "MQ","age": 25,"height": 183.52,"gender": false,"address": {"country": "China","zip-code": 123456},"subject": ["政治", "数学", "英语", "专业课"],"time": [123, 456, 789, 150],"grade": [66.51, 118.52, 61.53, 128.54],"student": [{"name": "张三","age": 24,"gender": true}, {"name": "李四","age": 25,"gender": true}, {"name": "王五","age": 26,"gender": true}]
}
2、解析(主要参考与使用)
2.1、解析 {}
int parsecjson_data(char *jsonstring)
{ cJSON *cjson= cJSON_Parse(jsonstring);if(cjson) {//解析 JSON 数据并处理cJSON *state = cJSON_GetObjectItem(cjson, "state");if (state != NULL && cJSON_IsString(state)) {printf("State: %s\n", state->valuestring); //字符串}cJSON *brightness = cJSON_GetObjectItem(cjson, "brightness");if (brightness != NULL && cJSON_IsNumber(brightness)) {printf("Brightness: %d\n", brightness->valueint); //整形}cJSON *height = cJSON_GetObjectItem(object2, "height"); if (height != NULL && cJSON_IsNumber(height)) {printf("height: %d \n", height->valuedouble); //浮点型}cJSON *gender = cJSON_GetObjectItem(object2, "gender"); if (gender != NULL && cJSON_IsBool(gender)) {printf("gender: %d \n", gender->type); //布尔类型 true/false}}cJSON_Delete(cjson);return 0;
}
2.2、解析[ {} {} ]
int parsecjson_data(char *jsonstring)
{ cJSON *cjson = cJSON_Parse(jsonstring);if (cjson != NULL && cJSON_IsArray(cjson)) {int array_size = cJSON_GetArraySize(cjson);if (array_size >= 2) {cJSON *object1 = cJSON_GetArrayItem(cjson, 0); // 获取数组中的第一个对象cJSON *object2 = cJSON_GetArrayItem(cjson, 1); // 获取数组中的第二个对象if (object1 != NULL && cJSON_IsObject(object1)) { // 第一个对象中的字段cJSON *sens1 = cJSON_GetObjectItem(object2, "K3"); // 第一个对象中有名为 K3 的字段if (sens1 != NULL && cJSON_IsNumber(sens1)) {car.sens1 = sens1->valueint;printf("sens1: %d \n", sens1->valueint);}} if (object2 != NULL && cJSON_IsObject(object2)) {cJSON *sens2 = cJSON_GetObjectItem(object2, "K4"); // 第二个对象中有名为 K4 的字段if (sens2 != NULL && cJSON_IsNumber(sens2)) {car.sens2 = sens2->valueint;printf("sens2: %d\n", sens2->valueint);}}}}cJSON_Delete(cjson);return 0;
}
3、解析(参考形式)
注释:借鉴参考文章
3.1、解析 {}
{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "interest"); // 获取object对象名if (item != NULL) {cJSON *val = NULL;val = cJSON_GetObjectItem(item, "basketball"); // 根据object对象名获得里面的basketball数据if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("basketball = %s\n", v_str);}val = cJSON_GetObjectItem(item, "badminton"); // 根据object对象名获得里面的badminton数据if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("badminton = %s\n", v_str);}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "interest");if (item != NULL) {cJSON *obj = item->child; // 获得 "basketball": "篮球"while (obj) {if (obj->type == cJSON_String) {char *v_str = obj->valuestring;printf("%s = %s\n", obj->string, v_str); // 可以通过string获得键}// 获取下一个元素obj = obj->next;}}
}
3.2、解析 [ ]
{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "color");if (item != NULL) {int size = cJSON_GetArraySize(item); // 获得数组个数for (int i = 0; i < size; i++) {cJSON *arr = cJSON_GetArrayItem(item, i); // 根据索引获得数组中的值if (arr != NULL && arr->type == cJSON_String) {v_str = arr->valuestring;printf("color = %s\n", v_str);}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "color");if (item != NULL) {cJSON *arr = item->child; // 获得 "black"while (arr) {if (arr->type == cJSON_String) {char *v_str = arr->valuestring;printf("color = %s\n", v_str);}// 获取下一个元素arr = arr->next;}}
}
3.3、解析 [ {} {} ]
{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {int size = cJSON_GetArraySize(item); // 获取的数组大小for (int i = 0; i < size; i++) {cJSON *obj = cJSON_GetArrayItem(item, i); // 获取的数组里的objcJSON *val = NULL;if (obj != NULL && obj->type == cJSON_Object) { // 判断数字内的元素是不是obj类型val = cJSON_GetObjectItem(obj, "game"); // 获得obj里的值if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("game = %s\n", v_str);}val = cJSON_GetObjectItem(obj, "price");if (val != NULL && val->type == cJSON_Number) {v_double = val->valuedouble;printf("price = %.2f\n", v_double);}}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {cJSON *obj = item->child; // 获得 { "game": "马里奥", "price": 66.6 }while (obj) {if (obj->type == cJSON_Object) {cJSON *objValue = obj->child; // 获得 "game": "马里奥"while (objValue) {// 再通过类型去区分if (objValue->type == cJSON_String) {char *v_str = objValue->valuestring;printf("%s = %s\n", objValue->string, v_str);} else if (objValue->type == cJSON_Number) {double v_double = objValue->valuedouble;printf("%s = %.2f\n", objValue->string, v_double);}// 获取下一个元素objValue = objValue->next;}}// 获取下一组元素obj = obj->next;}}
}
3.4、解析[ [ ] [ ] ]
{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {int size = cJSON_GetArraySize(item); // 获取的数组大小for (int i = 0; i < size; i++) {cJSON *arr = cJSON_GetArrayItem(item, i); // 解析获得 [ "小学", "初中" ]if (arr != NULL && arr->type == cJSON_Array) {int arrSize = cJSON_GetArraySize(arr);for (int j = 0; j < arrSize; j++) {cJSON *arr2 = cJSON_GetArrayItem(arr, j); // 再进一步解析就可以得到数组里面的元素了if (arr2 != NULL && arr2->type == cJSON_String) {v_str = arr2->valuestring;printf("education = %s\n", v_str);}}}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {cJSON *arr = item->child; // 获得 [ "小学", "初中" ]while (arr) {if (arr->type == cJSON_Array) {cJSON *arrValue = arr->child; // 获得 "小学"while (arrValue) {if (arrValue->type == cJSON_String) {char *v_str = arrValue->valuestring;printf("education = %s\n", v_str);}arrValue = arrValue->next; // 获取下一个元素}}// 获取下一组arr = arr->next;}}
}
3.5、解析 { { } { } }
{/*************** 方式一 ***************/char *arrStr[] = { "serialOne", "serialTwo" }; // 可以提前定义需要解析的对象键,这样就可以使用for循环进行解析了item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {cJSON *val = NULL;int size = sizeof(arrStr) / sizeof(char *);// 通过遍历指针数组,获得每个对象的键,在进行解析操作(如果不使用for循环解析,那就老老实实的写代码将全部个数解析完毕)for (int i = 0; i < size; i++) {cJSON *obj1 = cJSON_GetObjectItem(item, arrStr[i]);if (obj1 != NULL && obj1->type == cJSON_Object) {val = cJSON_GetObjectItem(obj1, "language");if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("education = %s\n", v_str);}val = cJSON_GetObjectItem(obj1, "grade");if (val != NULL && val->type == cJSON_Number) {v_int = val->valueint;printf("grade = %d\n", v_int);}}}}/*************** 方式二 ***************/// 在不知道键是什么的情况下 和 不知道有多少元素的情况下可用item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {// 获取到languages里的第一个子元素cJSON *obj = item->child; // 也就是:"serialOne": { "language": "汉语", "grade": 10 }while (obj) {if (obj->type == cJSON_Object) {// 获取到子元素的子元素cJSON *value = obj->child; // 也就是:{ "language": "汉语", "grade": 10 }while (value) {if (value->type == cJSON_String) {printf("%s = %s\n", value->string, value->valuestring);} else if (value->type == cJSON_Number) {printf("%s = %d\n", value->string, value->valueint);}// 通过next可以自由获取里面的元素了value = value->next;}}// 获得下一组子元素obj = obj->next;}}
}
参考文章
cJSON库用法详解
Cjson入门快速使用
使用cjson库 操作Json格式文件(创建、插入、解析、修改、删除)