C语言:解析cjson详解释

火影  金牌会员 | 2024-6-15 01:11:45 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 545|帖子 545|积分 1635

一、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 对象操作举例

创建一个对象,并向这个对象里添加字符串和整型键值:
  1. int main()
  2. {
  3.     cJSON * root;
  4.     cJSON *arry;
  5.     root=cJSON_CreateObject();                     // 创建根数据对象
  6.     cJSON_AddStringToObject(root,"name","danxia");  // 添加键值对
  7.     cJSON_AddStringToObject(root,"sex","woman");     // 添加键值对
  8.     cJSON_AddNumberToObject(root,"age",18);        // 添加键值对
  9.     char *out = cJSON_Print(root);   // 将json形式转换成字符串
  10.     printf("%s\n",out);
  11.     // 释放内存  
  12.     cJSON_Delete(root);  
  13.     free(out);        
  14. }
复制代码
运行结果:
  1. {
  2. "name": "danxia",
  3. "sex": "woman",
  4. "age": 18
  5. }
复制代码
Json 数组操作举例

创建一个数组,并向数组添加一个字符串和一个数字
  1. int main(int argc, char **argv)
  2. {
  3.     cJSON *root;
  4.     root = cJSON_CreateArray();
  5.     cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));
  6.     cJSON_AddItemToArray(root, cJSON_CreateNumber(18));
  7.     // char *s = cJSON_Print(root);
  8.     char *s = cJSON_PrintUnformatted(root);
  9.     if(s)
  10.     {
  11.         printf(" %s \n",s);
  12.         free(s);
  13.     }
  14.     cJSON_Delete(root);
  15.     return 0;
  16. }
复制代码
运行结果:
  1. ["Hello world",18]
复制代码
Json 对象、数组嵌套使用

对象内里包罗一个数组,数组内里包罗对象,对象内里再添加一个字符串和一个数字
  1. int main(int argc, char **argv)
  2. {
  3.     cJSON *root, *body, *list;
  4.     // josn 对象 root
  5.     root = cJSON_CreateObject();
  6.     // root 添加键值对 person:json数组A
  7.     cJSON_AddItemToObject(root,"person", body = cJSON_CreateArray());
  8.     // json数组A 添加Json对象B
  9.     cJSON_AddItemToArray(body, list = cJSON_CreateObject());
  10.     // 在json对象B中添加键值对: "name":"danxia"
  11.     cJSON_AddStringToObject(list,"name","danxia");
  12.     // 在json对象B中添加键值对: "age":18
  13.     cJSON_AddNumberToObject(list,"age",18);
  14.     // char *s = cJSON_Print(root);
  15.     char *s = cJSON_PrintUnformatted(root);
  16.     if(s)
  17.     {
  18.         printf(" %s \n",s);
  19.         free(s);
  20.     }
  21.     if(root)
  22.     {
  23.         cJSON_Delete(root);
  24.     }
  25.     return 0;
  26. }
复制代码
  1. {
  2.     "person":[{
  3.         "name":"danxia",
  4.         "age":18
  5.     }]
  6. }
复制代码
解析 Json 字符串

解析 Json 对象
C语言写的格式
  1. {"name":"danxia","sex":"woman","age":18}
复制代码
代码示例:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "cJSON.h"
  5. int main()
  6. {
  7.     cJSON *json, *name, *sex, *age;  
  8.     char* out="{"name":"luffy","sex":"man","age":19}";
  9.     json = cJSON_Parse(out); //解析成json形式
  10.     name = cJSON_GetObjectItem(json, "name");  //获取键值内容
  11.     sex = cJSON_GetObjectItem(json, "sex");
  12.     age = cJSON_GetObjectItem(json, "age");
  13.     printf("name:%s,sex:%s,age:%d\n", name->valuestring, sex->valuestring, age->valueint);
  14.     cJSON_Delete(json);  //释放内存
  15. }
复制代码
输出结果(串口实际显示):
  1. name:danxia,sex:woman,age:18
复制代码
解析嵌套的 Json 对象

解析一个嵌套的 Json 对象,数据如下:
{“list”:{“name”:“danxia”,“age”:18},“other”:{“name”:“ace”}}
  1. int main()
  2. {
  3.     char *s = "{"list":{"name":"danxia","age":18},"other":{"name":"ace"}}";
  4.     cJSON *root = cJSON_Parse(s);
  5.     if(!root)
  6.     {
  7.         printf("get root faild !\n");
  8.         return -1;
  9.     }
  10.     cJSON *js_list = cJSON_GetObjectItem(root, "list");
  11.     if(!js_list)
  12.     {
  13.         printf("no list!\n");
  14.         return -1;
  15.     }
  16.     printf("list type is %d\n",js_list->type);
  17.     cJSON *name = cJSON_GetObjectItem(js_list, "name");
  18.     if(!name)
  19.     {
  20.         printf("No name !\n");
  21.         return -1;
  22.     }
  23.     printf("name type is %d\n",name->type);
  24.     printf("name is %s\n",name->valuestring);
  25.     cJSON *age = cJSON_GetObjectItem(js_list, "age");
  26.     if(!age)
  27.     {
  28.         printf("no age!\n");
  29.         return -1;
  30.     }
  31.     printf("age type is %d\n", age->type);
  32.     printf("age is %d\n",age->valueint);
  33.     cJSON *js_other = cJSON_GetObjectItem(root, "other");
  34.     if(!js_other)
  35.     {
  36.         printf("no list!\n");
  37.         return -1;
  38.     }
  39.     printf("list type is %d\n",js_other->type);
  40.     cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
  41.     if(!js_name)
  42.     {
  43.         printf("No name !\n");
  44.         return -1;
  45.     }
  46.     printf("name type is %d\n",js_name->type);
  47.     printf("name is %s\n",js_name->valuestring);
  48.     if(root)
  49.     {
  50.         cJSON_Delete(root);
  51.     }
  52.     return 0;
  53. }
复制代码
结果为:
  1. list type is 6
  2. name type is 4
  3. name is danxia
  4. age type is 3
  5. age is 18
  6. list type is 6
  7. name type is 4
  8. name is ace
复制代码
标题解析 Json 数组

Json 字符串是一个 Json 数组格式,处置惩罚方式和 Json 对象差不多,好比我们要解析如下字符串:
{“names”:[“danxia”,“lucky”]}
  1. int main(int argc, char **argv)
  2. {
  3.     char *s = "{"names":["danxia","lucky"]}";
  4.     cJSON *root = cJSON_Parse(s);
  5.     if(!root)
  6.     {
  7.         printf("get root faild !\n");
  8.         return -1;
  9.     }
  10.     cJSON *js_list = cJSON_GetObjectItem(root, "names");
  11.     if(!js_list)
  12.     {
  13.         printf("no list!\n");
  14.         return -1;
  15.     }
  16.     int array_size = cJSON_GetArraySize(js_list);
  17.     printf("array size is %d\n",array_size);
  18.     for(int i=0; i< array_size; i++)
  19.     {
  20.         cJSON *item = cJSON_GetArrayItem(js_list, i);
  21.         printf("item type is %d\n",item->type);
  22.         printf("%s\n",item->valuestring);
  23.     }
  24.     if(root)
  25.     {
  26.         cJSON_Delete(root);
  27.     }
  28.     return 0;
  29. }
复制代码
标题解析嵌套的 Json 对象和数组

Json 字符串最复杂:莫过于 Json 对象和 Json 数组嵌套的形式.
下面通过一个例子演示一下应该如何解析,字符串格式如下:
{“list”:[{“name”:“danxia”,“age”:18},{“name”:“guizhong”,“age”:19}]}
在解析的时候,我们只须要按照从属关系,一层层解析即可:
根节点是一个 Json 对象,基于根节点中的 key 值取出对应的 value 值,得到一个 Json 数组
读出 Json 数组的巨细,遍历里边的各个元素,每个元素都是一个 Json 对象
将 Json 对象中的键值对根据 key 值取出对应的 value 值
从取出的 Value 值中读出实际类型对应的数值 示例代码如下:
  1. #include "cJSON.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int main(int argc, char **argv)
  5. {
  6.     char *s = "{"list":[{"name":"danxia","age":18},{"name":"guizhong","age":19}]}";
  7.     cJSON *root = cJSON_Parse(s);
  8.     if(!root)
  9.     {
  10.         printf("get root faild !\n");
  11.         return -1;
  12.     }
  13.     cJSON *list = cJSON_GetObjectItem(root, "list");
  14.     if(!list)
  15.     {
  16.         printf("no list!\n");
  17.         return -1;
  18.     }
  19.     int array_size = cJSON_GetArraySize(list);
  20.     printf("array size is %d\n",array_size);
  21.    
  22.     for(int i=0; i< array_size; i++)
  23.     {
  24.         cJSON* item = cJSON_GetArrayItem(list, i);
  25.         cJSON* name = cJSON_GetObjectItem(item, "name");
  26.         printf("name is %s\n",name->valuestring);
  27.         cJSON* age = cJSON_GetObjectItem(item, "age");
  28.         printf("age is %d\n",age->valueint);
  29.     }
  30.     if(root)
  31.     {
  32.         cJSON_Delete(root);
  33.     }
  34.     return 0;
  35. }
复制代码
结果为
  1. 在这里插入代码片
复制代码
其他例子:
  1. {
  2.     "code":"a2024",
  3.     "cmd":1,
  4.     "data":[   
  5.         {
  6.             "name":"danxia",
  7.             "port":88
  8.         },
  9.         {
  10.             "name":"meixa",
  11.             "port":89
  12.         }
  13.     ]
  14. }
复制代码
解析上面的json串
  1. char data[256] = "{"code":"a2024","cmd":1,"data":[{"name":"a","port":88},{"name":"b","port":89}]}";
  2.     cJSON *json=cJSON_Parse(data);
  3.     cJSON *item = cJSON_GetObjectItem(json,"code");
  4.     printf("scode : %s\n",item->valuestring);
  5.     item = cJSON_GetObjectItem(json,"cmd");
  6.     printf("cmd   : %d\n",item->valueint);
  7.     cJSON *d_list = cJSON_GetObjectItem(json,"data");
  8.     int arr_size = cJSON_GetArraySize(d_list);
  9.     cJSON* arr_item_list = d_list->child;
  10.     int i = 0;
  11.     int j = 0;
  12.     for(i=0;i <=(arr_size-1);++i){
  13.         cJSON *send_list = cJSON_GetObjectItem(arr_item_list,"name");
  14.         printf("ip : %s\n",send_list->valuestring);
  15.         send_list = cJSON_GetObjectItem(arr_item_list,"port");
  16.         printf("port   : %d\n",send_list->valueint);
  17.         arr_item_list = arr_item_list->next;
  18.     }
  19.     cJSON_Delete(json);
复制代码
实用的注意要点:

注意:芯片堆栈巨细的设置:0xC00

在线解析JSON格式数据工具
https://www.bejson.com/
https://www.sojson.com/
持续更新中,有什么好的工具大概东西,欢迎评价留言,谢谢

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表