在c语言里用到json格式的字符串,拼接起来就很麻烦,如果数据大,需要申请空间,如果中间要再插入一个子项,还需要麻烦的拷贝拼接。
用cJSon库的好处就是:
1、拼接、插入方便。临时增加,修改,直接用对于的接口来实现,快速,方便。
2、空间申请问题由接口底层去实现。如果拼接很多,内存问题我们不用去过多考虑,只要知道怎么用就可以避免内存泄露问题。
3、格式统一。书写方便,可能有些地方会加中括号,有些没有。用这个可以省掉这种麻烦。
4、使用拓展方便。需要临时增加,或者再加入内容,比较便捷,高效。不用再自己用一大串的转义符加双引号来拼接了。
1、JSON格式:一对大括号,相当于XML的头和尾,内部全是键值对
{
"name" : "apple",
"sex" : "famale",
"high" : "178",
"girls":["alice", "ruby", "kit"],
"家电" :{"TV":"changhong"}
}
注:结合JSON视图工具,可以把JSON数据结构化展示出来,清晰明了
1、一对大括号括起内容
2、内部使用key:value
key值为字符串
value值可以取值:字符串、数值类型、数组类型[]、对象{}、NULL、布尔值
2、cJSON库
在GitHub上下载对应的cJSON库(cJson-master),注:解码后内部只有cJSON.h和cJSON.c可以供我们使用,也就是直接使用cJSON的源码,用时把这两个文件拷到开发目录下即可
/*内部函数简介:*/
1、cJson_Parse(char*) //用于解析利用C字符串存储的json字符串
会生成一个cJSON格式的结构体
2、cJson_Print(cJson*) //用于输出json字符串解析后的数据
把cJSON结构体转换成C字符串
3、cJson_Delete(cJson*)//释放cJson*类型数据
简单使用:
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main(void)
{
char *data = "{\"love\":[\"LOL\", \"Go shopping\"]}";
//解析data字符串,存储成cJSON结构体
cJSON *json = cJSON_Parse(data);
char *json_data = NULL;
printf("data : %s\n", json_data = cJSON_Print(json));
free(json_data);
cJSON_Delete(json);
return 0;
}
注:测试文件需要使用数学库,需要加入-lm
加数学库:-lm
注:不是-lmath
floor:向下取整
ceil:向上取整
3、基于JSON相关的C库函数,生成对应的json文件
注:快捷方式:[ + d:快速列出宏定义
<1>创建一个值类型的数据
注:不管什么类型的数据转换后都是cJSON结构体
extern cJSON* cJSON_CreateNumber(double num)
extern cJSON* cJSON_CreateString(const char *string)
extern cJSON* cJSON_CreateArray(void)
<2>创建一个对象(文档)
extern cJSON* cJSON_CreateObject(void); //创建json对象,相当于创建了一对{}
<3>数组创建及添加
cJSON* cJSON_CreateIntArray(const int *numbers, int count)
void cJSON_AddItemToArray(cJSON *array, cJSON *item)
//例子
cJSON* array = NULL;
cJSON_AddItemToArray(array, cJSON_CreateString("LOL"));
cJSON_AddItemToArray(array, cJSON_CreateString("NBA"));
cJSON_AddItemToArray(array, cJSON_CreateString("Shopping"));
4、JSON嵌套
<1>向对象中增加键值对
cJSON_AddItemToObject(root, "rows", 值数据类型的相关函数());
<2>在对象中增加数组
cJSON_AddItemToObject(root, "rows", cJSON_CreateArray());
<3>向数组中增加对象
cJSON_AddItemToArray(rows, cJSON_CreateObject());
<4>几个可以提高操作效率的宏函数
#define cJSON_AddNumberToObject(object, name, n) \
cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object, name, s) \
cJSON_AddItemToObejct(object, name, cJSON_CreateString(s))
<5>添加一个元素到json对象中:cJSON_AddItemToObject(json, “key”, value)
value取值:
字符串 ---》cJSON_CreateString("value");
数值 ---》cJSON_CreateNumber(29);
数组 ---》cJSON_CreateArray(void);
对象 ---》cJSON_CreateObject(void);
5、json文件创建方法
----》json = cJSON_CreateObject(); //相当于创建一个大括号
----》cJSON_AddItemToObject(json, "name", cJSON_CreateString("hmh")) //json对象加元素
{
"name":"hmh", ---->cJSON_CreateString("hmh")
"age":28,
}
6、创建json文件案例
注:gcc -o demo test2.c cJSON.* -lm
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cJSON.h"
int main(void)
{
//创建一个空的文档对象
cJSON* json = cJSON_CreateObject();
//向文档中增加一个键值对{"name":"hmh"}
//======>cJSON_AddStringToObject(json, "name", "hmh")
cJSON_AddItemToObject(json, "name", cJSON_CreateString("hmh"));
cJSON_AddItemToObject(json, "age", cJSON_CreateNumber(29));
cJSON* array = NULL;
cJSON_AddItemToObject(json, "love", array = cJSON_CreateArray());
cJSON_AddItemToArray(array, cJSON_CreateString("LOL"));
cJSON_AddItemToArray(array, cJSON_CreateString("NBA"));
cJSON_AddItemToArray(array, cJSON_CreateString("Shopping"));
//宏的使用
cJSON_AddNumberToObject(json, "score", 59);
cJSON_AddStringToObject(json, "address", "beijing");
//将json结构体格式化到缓冲区
char *buf = cJSON_Print(json);
//打开文件用以写入json数据
FILE *fp = fopen("test2.json", "w");
fwrite(buf, 1, strlen(buf), fp);
free(buf);
fclose(fp);
//释放json结构体所占的内存
cJSON_Delete(json);
return 0;
}
7、特别注意
在上面我们对cJSON进行了一些简单分析,包括解析、打包这两种最常用功能,cJSON的移植相对简单,但是在使用的时候,还是有一些特别需要注意的地方的,这 主要是因为 cJSON库 中的一些函数会进行内存申请操作,但是并不会自动释放内存,这就相当于 是风险, 需要使用者自己去及时的释放 内存。如果处理不当,会造成内存用完,进而程序也运行不了多久就废掉了。所以需要特别注意的地方:
(1)使用cJSON_Parse创建一个 cJSON指针后,用完务必 使用 cJSON_Delete函数释放 该cJSON指针。
(2)使用cJSON_Createxxx函数创建 json对象后, 用完务必使用 cJSON_Delete函数释放 该cJSON指针。
(3)使用 cJSON_Print函数 将cJSON数据 解析成 char 字符串后,务必使用 cJSON_free函数释放 该char指针,这个 细节隐藏的很深,因为cJSON_Print 函数不光是 print打印,他会 调用cJSON_malloc 申请内存,所以用完 必须要释放 掉 该char 指针。
cJSON_Delete(root); //非常重要!!!!!!
CJSON_free(payload); //非常重要!!!!!!