行业知识
C语言:解析cjson详解释
一、json是什么
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。-- 来自百度百科
二、 json介绍
1.下载cJSON库文件
cJSON库文件一共两个文件:cJSON.h和cJSON.c。下载地址
2.语法
数据在名称/值对中,key : value
JSON key 必须是字符串
数据由逗号分隔
大括号 {} 保存对象
中括号 [] 保存数组,数组可以包含多个对象
3.JSON value 值
JSON 值可以是:字符串, 数字, 对象, 数组, 布尔值或 null
数字(整数或浮点数)
JSON 数字可以是整型或者浮点型:
{ “age”:30 }
字符串(在双引号中)
{ “name”:“danxia”}
逻辑值(true 或 false)
JSON 布尔值可以是 true 或者 false:
{ “flag”:true }
数组(在中括号[]中)
数组值必须是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。
如:
{
“name”:“danxia”,
“age”:18,
“sites”:[ “Google”, “baidu”, “google” ]
}
数组可包含多个对象:
{
“sites”: [
{ “name”:“danxia” , “url”:“www.Google.com” },
{ “name”:“meixia” , “url”:“www.baidu.com” },
{ “name”:“meidi” , “url”:“www.google.com” }
]
}
对象(在大括号{}中)
JSON 对象使用在大括号({})中书写。
对象可以包含多个 key/value(键/值)对。
key 必须是字符串,value 可以是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。
key 和 value 中使用冒号(:)分割。
每个 key/value 对使用逗号(,)分割。
JSON 对象在大括号 {} 中书写:
{key1 : value1, key2 : value2, … keyN : valueN }
对象可以包含多个名称/值对:
{ “name”:“danxia” , “url”:“www.Google.com” }
JSON 可以设置 null 值:
{ “runoob”:null }
三、数据封装
核心结构体
typedef struct cJSON {
struct cJSONnext,prev; / 遍历数组或对象链的前向或后向链表指针/
struct cJSON child; /数组或对象的孩子节点/
int type; / key的类型*/
char valuestring; /字符串值/
int valueint; / 整数值*/
double valuedouble; /* 浮点数值*/
char string; / key的名字*/
} cJSON;
关于该结构体的几点说明:
cJOSN 结构体是一个双向链表,并且可通过child 指针访问下一层。
结构体成员 type 变量用于描述数据元素的类型(如果是键值对表示 value 值的类型),数据元素可以是字符串、整形、浮点型。
如果是整形值的话可通过 valueint 将值取出
如果是浮点型的话可通过 valuedouble 将值取出
如果是字符串类型的话可通过 valuestring 将值取出
结构体成员 string 表示键值对中键值的名称
核心封装
封装函数
// 空值类型
extern cJSON *cJSON_CreateNull(void);
// 布尔类型
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
// 数值类型
extern cJSON *cJSON_CreateNumber(double num);
// 字符串类型
extern cJSON *cJSON_CreateString(const char *string);
// json数组(创建空数组)
extern cJSON *cJSON_CreateArray(void);
// json对象(创建空对象)
extern cJSON *cJSON_CreateObject(void);
创建数组类型函数
// 创建一个Json数组, 元素为整形
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
// 创建一个Json数组, 元素为浮点
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
// 创建一个Json数组, 元素为字符串类型
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
释放取消类型函数
//删除JSON结构体
extern cJSON *cJSON_Delete(cJSON *item)
//清空JSON占用的内存空间
static void CJSON_CDECL internal_free(void *pointer)
cJSON_CreateObject 函数可创建一个根对象,返回的是一个 cJSON 指针,在这个指针用完了以后,需要手动调用 cJSON_Delete(root) 进行内存回收。
函数 cJSON_Print() 内部封装了 malloc 函数,所以需要使用 free() 函数释放被 out 占用的内存空间。
Json 数据的封装
Json 对象操作举例
创建一个对象,并向这个对象里添加字符串和整型键值:
int main(){ cJSON * root; cJSON *arry; root=cJSON_CreateObject(); // 创建根数据对象 cJSON_AddStringToObject(root,"name","danxia"); // 添加键值对 cJSON_AddStringToObject(root,"sex","woman"); // 添加键值对 cJSON_AddNumberToObject(root,"age",18); // 添加键值对 char *out = cJSON_Print(root); // 将json形式转换成字符串 printf("%s\n",out); // 释放内存 cJSON_Delete(root); free(out); } 运行结果:
{ "name": "danxia", "sex": "woman", "age": 18} Json 数组操作举例
创建一个数组,并向数组添加一个字符串和一个数字
int main(int argc, char **argv){ cJSON *root; root = cJSON_CreateArray(); cJSON_AddItemToArray(root, cJSON_CreateString("Hello world")); cJSON_AddItemToArray(root, cJSON_CreateNumber(18)); // char *s = cJSON_Print(root); char *s = cJSON_PrintUnformatted(root); if(s) { printf(" %s \n",s); free(s); } cJSON_Delete(root); return 0;} 运行结果:
["Hello world",18]
Json 对象、数组嵌套使用
对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字
int main(int argc, char **argv){ cJSON *root, *body, *list; // josn 对象 root root = cJSON_CreateObject(); // root 添加键值对 person:json数组A cJSON_AddItemToObject(root,"person", body = cJSON_CreateArray()); // json数组A 添加Json对象B cJSON_AddItemToArray(body, list = cJSON_CreateObject()); // 在json对象B中添加键值对: "name":"danxia" cJSON_AddStringToObject(list,"name","danxia"); // 在json对象B中添加键值对: "age":18 cJSON_AddNumberToObject(list,"age",18); // char *s = cJSON_Print(root); char *s = cJSON_PrintUnformatted(root); if(s) { printf(" %s \n",s); free(s); } if(root) { cJSON_Delete(root); } return 0;} { "person":[{ "name":"danxia", "age":18 }]} 解析 Json 字符串
解析 Json 对象
C语言写的格式
{\"name\":\"danxia\",\"sex\":\"woman\",\"age\":18} 代码示例:
#include #include #include #include "cJSON.h" int main(){ cJSON *json, *name, *sex, *age; char* out="{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}"; json = cJSON_Parse(out); //解析成json形式 name = cJSON_GetObjectItem(json, "name"); //获取键值内容 sex = cJSON_GetObjectItem(json, "sex"); age = cJSON_GetObjectItem(json, "age"); printf("name:%s,sex:%s,age:%d\n", name->valuestring, sex->valuestring, age->valueint); cJSON_Delete(json); //释放内存 } 输出结果(串口实际显示):
name:danxia,sex:woman,age:18
解析嵌套的 Json 对象
解析一个嵌套的 Json 对象,数据如下:
{“list”:{“name”:“danxia”,“age”:18},“other”:{“name”:“ace”}}
int main(){ char *s = "{\"list\":{\"name\":\"danxia\",\"age\":18},\"other\":{\"name\":\"ace\"}}"; cJSON *root = cJSON_Parse(s); if(!root) { printf("get root faild !\n"); return -1; } cJSON *js_list = cJSON_GetObjectItem(root, "list"); if(!js_list) { printf("no list!\n"); return -1; } printf("list type is %d\n",js_list->type); cJSON *name = cJSON_GetObjectItem(js_list, "name"); if(!name) { printf("No name !\n"); return -1; } printf("name type is %d\n",name->type); printf("name is %s\n",name->valuestring); cJSON *age = cJSON_GetObjectItem(js_list, "age"); if(!age) { printf("no age!\n"); return -1; } printf("age type is %d\n", age->type); printf("age is %d\n",age->valueint); cJSON *js_other = cJSON_GetObjectItem(root, "other"); if(!js_other) { printf("no list!\n"); return -1; } printf("list type is %d\n",js_other->type); cJSON *js_name = cJSON_GetObjectItem(js_other, "name"); if(!js_name) { printf("No name !\n"); return -1; } printf("name type is %d\n",js_name->type); printf("name is %s\n",js_name->valuestring); if(root) { cJSON_Delete(root); } return 0;} 结果为:
list type is 6name type is 4name is danxiaage type is 3age is 18list type is 6name type is 4name is ace
标题解析 Json 数组
Json 字符串是一个 Json 数组格式,处理方式和 Json 对象差不多,比如我们要解析如下字符串:
{“names”:[“danxia”,“lucky”]}
int main(int argc, char **argv){ char *s = "{\"names\":[\"danxia\",\"lucky\"]}"; cJSON *root = cJSON_Parse(s); if(!root) { printf("get root faild !\n"); return -1; } cJSON *js_list = cJSON_GetObjectItem(root, "names"); if(!js_list) { printf("no list!\n"); return -1; } int array_size = cJSON_GetArraySize(js_list); printf("array size is %d\n",array_size); for(int i=0; itype); printf("%s\n",item->valuestring); } if(root) { cJSON_Delete(root); } return 0;} 标题解析嵌套的 Json 对象和数组
Json 字符串最复杂:莫过于 Json 对象和 Json 数组嵌套的形式.
下面通过一个例子演示一下应该如何解析,字符串格式如下:
{“list”:[{“name”:“danxia”,“age”:18},{“name”:“guizhong”,“age”:19}]}
在解析的时候,我们只需要按照从属关系,一层层解析即可:
根节点是一个 Json 对象,基于根节点中的 key 值取出对应的 value 值,得到一个 Json 数组
读出 Json 数组的大小,遍历里边的各个元素,每个元素都是一个 Json 对象
将 Json 对象中的键值对根据 key 值取出对应的 value 值
从取出的 Value 值中读出实际类型对应的数值 示例代码如下:
#include "cJSON.h"#include #include int main(int argc, char **argv){ char *s = "{\"list\":[{\"name\":\"danxia\",\"age\":18},{\"name\":\"guizhong\",\"age\":19}]}"; cJSON *root = cJSON_Parse(s); if(!root) { printf("get root faild !\n"); return -1; } cJSON *list = cJSON_GetObjectItem(root, "list"); if(!list) { printf("no list!\n"); return -1; } int array_size = cJSON_GetArraySize(list); printf("array size is %d\n",array_size); for(int i=0; ivaluestring); cJSON* age = cJSON_GetObjectItem(item, "age"); printf("age is %d\n",age->valueint); } if(root) { cJSON_Delete(root); } return 0;} 结果为
在这里插入代码片
其他例子:
{ "code":"a2024", "cmd":1, "data":[ { "name":"danxia", "port":88 }, { "name":"meixa", "port":89 } ]} 解析上面的json串
char data[256] = "{\"code\":\"a2024\",\"cmd\":1,\"data\":[{\"name\":\"a\",\"port\":88},{\"name\":\"b\",\"port\":89}]}"; cJSON *json=cJSON_Parse(data); cJSON *item = cJSON_GetObjectItem(json,"code"); printf("scode : %s\n",item->valuestring); item = cJSON_GetObjectItem(json,"cmd"); printf("cmd : %d\n",item->valueint); cJSON *d_list = cJSON_GetObjectItem(json,"data"); int arr_size = cJSON_GetArraySize(d_list); cJSON* arr_item_list = d_list->child; int i = 0; int j = 0; for(i=0;i cJSON *send_list = cJSON_GetObjectItem(arr_item_list,"name"); printf("ip : %s\n",send_list-valuestring); send_list = cJSON_GetObjectItem(arr_item_list,"port"); printf("port : %d\n",send_list->valueint); arr_item_list = arr_item_list->next; } cJSON_Delete(json); 实用的注意要点:
注意:芯片堆栈大小的设置:0xC00
在线解析JSON格式数据工具
https://www.bejson.com/
https://www.sojson.com/
持续更新中,有什么好的工具或者东西,欢迎评价留言,谢谢