了解CJSON
JSON: JavaScript 对象表示法( JavaScript Object Notation) 。是一种轻量级的数据交换格式。 它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式, 但是也使用了类似于C语言家族的习惯( 包括C、 C++、 C#、 Java、 JavaScript、 Perl、 Python等) 。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写, 同时也易于机器解析和生成(一般用于提升网络传输速率)。
JSON 解析器和 JSON 库支持许多不同的编程语言。 JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。 由于这种相似性, 无需解析器, JavaScript 程序能够使用内建的 eval() 函数, 用 JSON 数据来生成原生的 JavaScript 对象。
JSON 是存储和交换文本信息的语法。 类似 XML。 JSON 比 XML 更小、 更快, 更易解析。
JSON 具有自我描述性, 语法简洁, 易于理解。
JSON的数据类型
● number:和JavaScript的number完全一致;相当于C中的int类型
● boolean:就是JavaScript的true或false;相当于c++中的bool类型
● string:就是JavaScript的string;相当于c++的string类型
● null:就是JavaScript的null;相当于C的NULL类型
● array:就是JavaScript的Array表示方式——[];相当于C的数组
● object:就是JavaScript的{ … }表示方式。相当于C++的类或者C的结构体
格式规范
● json以大括号起始和结尾
● 内容都是以键值对的形式存在
● 所有的键都是字符串
● 值的类型不一定,属于JavaScript 的基本数据类型
● 每个键值对以,分割
● 最后一个键值对不加逗号
{
"stars": [
{
"name": "Faye",
"address": "北京"
},
{
"name": "andy",
"address": "香港"
},
{
"name": "eddie",
"address": "台湾"
},
]
}
序列化与反序列化
Json序列化:可以理解为利用程序生成Json字符串的过程。
Json反序列化:可以理解为利用程序将已有的Json字符串解析出我们需要的值的过程。
序列化
常用库函数如下
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*) cJSON_AddNullToObject(cJSON * const object, const char * const name);//在对象中添加null
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);//在对象中添加true
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);//在对象中添加false
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_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); //在对象中添加项目
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);//在数组中添加项目
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);//JSON数据结构转换为JSON字符串---有格式
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); //JSON数据结构转换为JSON字符串---无格式
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); //清除结构体
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);//创建数字
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);//创建字符串
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);//创建浮点型数组
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);//创建字符型数组
示例代码
//序列化
cJSON *root = cJSON_CreateObject();
cJSON *login_1 = cJSON_CreateObject();
cJSON_AddItemToObject(root, "ver", cJSON_CreateString("1.0"));
cJSON_AddItemToObject(root, "login", login_1);
cJSON_AddItemToObject(login_1, "user", cJSON_CreateString("zhangsan"));
cJSON_AddItemToObject(login_1, "pwd", cJSON_CreateString("123456"));
cJSON *data_1 = cJSON_CreateArray();
cJSON_AddItemToObject(root, "data", data_1);
for (int j = 0; j < data_size; j++)
{
cJSON *key_t = cJSON_CreateObject();
//三个数组数据
//key 1-2-3
//type 2-1-3
//val "10"-"0"-"22.5"
cJSON_AddItemToObject(key_t, "key", cJSON_CreateNumber(key[j]));
cJSON_AddItemToObject(key_t, "type", cJSON_CreateNumber(type[j]));
cJSON_AddItemToObject(key_t, "val", cJSON_CreateString(val[j]));
cJSON_AddItemToArray(data_1, key_t);
}
printf("%s\n", cJSON_Print(root));
输出结果
{
"ver": "1.0",
"login": {
"user": "zhangsan",
"pwd": "123456"
},
"data": [{
"key": 1,
"type": 2,
"val": "10"
},
{
"key": 2,
"type": 1,
"val": "0"
},
{
"key": 3,
"type": 3,
"val": "22.5"
}
]
}
反序列化
常用库函数如下
cJSON *cJSON_Parse(const char *value);
/*作用:将一个JSON数据包,按照cJSON结构体的结构序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体
返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL*/
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/*作用:获取JSON字符串字段值
返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL*/
int cJSON_GetArraySize(cJSON *array);
/*作用:获取数组成员对象个数
返回值:数组成员对象个数*/
void cJSON_Delete(cJSON *c);
/*作用:释放位于堆中cJSON结构体内存
返回值:无*/
示例代码
cJSON *cjson = cJSON_Parse(buf);//buf存储上面序列化的输出结果
if (cjson == NULL)
{
perror("cjson_parse error\n");
return -1;
}
else
{
printf("%s\n", cJSON_Print(cjson));
}
char *ver = cJSON_GetObjectItem(cjson, "ver")->valuestring;
printf("ver : %s\n", ver);
cJSON *login = cJSON_GetObjectItem(cjson, "login");
char *user = cJSON_GetObjectItem(login, "user")->valuestring;
char *pwd = cJSON_GetObjectItem(login, "pwd")->valuestring;
printf("login :\nuser : %s\tpwd : %s\n", user, pwd);
cJSON *data = cJSON_GetObjectItem(cjson, "data");
int data_size = cJSON_GetArraySize(data);
cJSON *data_child = data->child;
int key[3] = {};
int type[3] = {};
char *val[3] = {};
for (int j = 0; j < data_size; j++)
{
key[j] = cJSON_GetObjectItem(data_child, "key")->valueint;
type[j] = cJSON_GetObjectItem(data_child, "type")->valueint;
val[j] = cJSON_GetObjectItem(data_child, "val")->valuestring;
data_child = data_child->next;
}
for (int j = 0; j < data_size; j++)
{
printf("%d %d %s\n", key[j], type[j], val[j]);
}
输出结果
ver : 1.0
login :
user : zhangsan pwd : 123456
key = 3,type = 3,val = 22.500000
key = 2,type = 1,val = 0
key = 1,type = 2,val = 10