赞
踩
目录
JSON(JavaScript object Notation),即JavaScript 对象符号,是一种轻量级的数据格式;【其本质就是字符串】
它采用完全独立于编程语言的文本格式来存储和表示数据,语法简洁,层次结构清晰,易于人阅读和编写,同时也易于机器解析和生成,有效的提升了网络传送效率。
因为它完全独立于编程语言所以支持跨平台开发;
JSON 的名称中虽然带有JavaScript,但这是指其语法规则是参考JavaScript对象的,而不是指只能用于JavaScript 语言。
因为JSON本身就是参考JavaScript 对象的规则定义的,其语法与JavaScript定义对象的语法几乎完全相同。
JSON可以将数据转换为字符串,接着在网络中或者程序里面传递这个字符串,最后可以还原成各个编程语言所支持的数据格式;
JSON是一个无序的键值对(key / value)集合;
JSON以"{“开始,以”}"结束,允许嵌套使用
每个key(关键字)和value(值)成对出现,关键字和值之间使用":"分隔
键/值对之间用","分隔
在这些字符前后允许存在无意义的空白符
数组(Array)用方括号(“[]”)表示。
对象(0bject)用大括号(“{}”)表示。
名称/值对(name/value)组合成数组和对象。
名称(name)置于双引号中,值(value)有字符串、数值、布尔值、null、对象和数组。
并列的数据之间用逗号(“,”)分隔
在线的JSON解析网站如下:JSON解析
如下是一个实际的例子,来体会一下JSON:
- {
- "name": "JK",
- "age": 18,
- "height": 175,
- "sex": false,
-
-
- "address": {
- "country": "China",
- "tel": 123456
- },
-
-
- "subject": ["语文", "数学", "英语"],
- "grade": [1, 2, 3],
-
-
- "student": [{
- "name": "wsf",
- "age": 23,
- "sex": true
- },
- {
- "name": "rs",
- "age": 25,
- "sex": true
- }
- ]
- }
JSON树可视化
CJSON对象的实现采用了树形结构,每一个对象就是树的一个节点,每个节点由cJSON这个结构体组成,对象中的元素也由cJSON这个结构体组成。同一层的对象和元素是双向链表结构,由next和prev指针链接。不同层的对象或元素由child指针链接起来。type表示对象或元素类型,string表示对象或节点的名称。元素的值存储在valuestring, valueint和valuedouble中;
cJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。
要使用CJSON,直接把项目从Github上clone下来,接着把CJSON.h,CJSON.c这两个源文件加入到工程中就行,使用时include CJSON.h头文件就行;
cJSON使用cJSON结构体来表示一个JSON数据,定义在cJSON.h中,源码如下:
- //逻辑值的宏定义
- #define cJSON_Invalid (0)
- #define cJSON_False (1 << 0)
- #define cJSON_True (1 << 1)
- #define cJSON_NULL (1 << 2)
- #define cJSON_Number (1 << 3)
- #define cJSON_String (1 << 4)
- #define cJSON_Array (1 << 5)
- #define cJSON_Object (1 << 6)
- #define cJSON_Raw (1 << 7) /* raw json */
-
-
- #define cJSON_IsReference 256
- #define cJSON_StringIsConst 512
-
-
- /* The cJSON structure: */
- typedef struct cJSON
- {
- /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
- struct cJSON *next;
- struct cJSON *prev;
- /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
- struct cJSON *child;
-
-
- /* The type of the item, as above. */
- 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 valueint;
- /* The item's number, if type==cJSON_Number */
- 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;
首先,CJSON不是将一整段JSON数据全抽象出来,而是将其中的一条JSON数据抽象出来,也就是一个键值对,用上面的结构体 strcut cJSON 来表示,其中用来存放值的成员列表如下:
String:用于表示该键值对的名称;
type:用于表示该键值对中值的类型;
valuestring:如果键值类型(type)是字符串,则将该指针指向键值;
valueint:如果键值类型(type)是整数,则将该指针指向键值;
valuedouble:如果键值类型(type)是浮点数,则将该指针指向键值;
一段完整的JSON数据中由很多键值对组成,并且涉及到键值对的查找、删除、添加,所以使用链表来存储整段JSON数据,如上面的代码所示:
next指针:指向下一个键值对
prev指针指向上一个键值对
因为JSON数据支持嵌套,所以一个键值对的值会是一个新的JSON数据对象(一条新的链表),也有可能是一个数组,方便起见,在cJSON中,数组也表示为一个数组对象,用链表存储,所以:在键值对结构体中,当该键值对的值是一个嵌套的JSON数据或者一个数组时,由child指针指向该条新链表;
链表中的一些概念:
头指针:指向链表头结点的指针;
头结点:不存放有效数据,方便链表操作;
首节点:第一个存放有效数据的节点;
尾节点:最后一个存放有效数据的节点;
- extern cJSON * cJSON_CreateObject(void); //创建对象
-
-
- extern cJSON * cJSON_CreateArray(void); //创建数组
-
-
- extern cJSON * cJSON_CreateIntArray(const int *numbers, int count);//创建整型数组
-
-
- extern cJSON * cJSON_CreateDoubleArray(const double *numbers, int count);//创建双浮点型数组
-
-
- extern cJSON* cJSON_AddNullToObject(cJSON * const object, const char * const name);//在对象中添加null
-
-
- extern cJSON* cJSON_AddTrueToObject(cJSON * const object, const char * const name);//在对象中添加true
-
-
- extern cJSON* cJSON_AddFalseToObject(cJSON * const object, const char * const name);//在对象中添加false
-
-
- extern cJSON* cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);//在对象中添加数字
-
-
- extern cJSON* cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);//在对象中添加字符串
-
-
- extern cJSON_bool cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); //在对象中添加项目
-
-
- extern cJSON_bool cJSON_AddItemToArray(cJSON *array, cJSON *item);//在数组中添加项目
-
-
- extern char * cJSON_Print(const cJSON *item);//JSON数据结构转换为JSON字符串---有格式
- extern char * cJSON_PrintUnformatted(const cJSON *item); //JSON数据结构转换为JSON字符串---无格式
-
-
- extern void cJSON_Delete(cJSON *item); //清除结构体
-
-
- #include "string.h"
- #include "cJSON.h"
- #include "stdio.h"
-
-
-
-
-
-
- int main()
- {
- // 创建头指针
- cJSON *JSON_Root = NULL;
-
-
- // 创建头结点,并将头指针指向头结点(可以看做是一个树的根root)
- JSON_Root = cJSON_CreateObject();
-
-
- // 添加一条字符串类型的JSON数据
- cJSON_AddStringToObject(JSON_Root, "name", "zhuhua");
-
-
- // 添加一条浮点类型的JSON数据(添加一个链表结点)到root下
- cJSON_AddNumberToObject(JSON_Root, "height", 66.6666);
-
-
- // 添加一条整数型的JSON数据(链表结点)
- cJSON_AddNumberToObject(JSON_Root, "grade", 100);
-
-
- // 添加一个嵌套的JSON数据(添加一个链表节点, 又一个《对象》)
- cJSON *timeCode = cJSON_CreateObject();
-
-
- // true
- cJSON_AddTrueToObject(timeCode, "Sex");
-
-
- cJSON_AddStringToObject(timeCode, "datatime", "20220811");
-
-
- cJSON_AddFalseToObject(timeCode, "Judge");
-
-
- // 最后把这个对象加入到root下
- cJSON_AddItemToObject(JSON_Root, "TIMECODE", timeCode);
-
-
- // 再次嵌套,加入一个数组类型的JSON数据,在timecode结点之下(添加一个链表结点)
- cJSON *dataCode = cJSON_CreateArray();
- // 两种方式添加
- cJSON_AddStringToObject(dataCode, "", "English");
-
-
- cJSON_AddItemToArray(dataCode, cJSON_CreateString("zhuzhuzhu"));
-
-
- cJSON_AddStringToObject(dataCode, "", "huahuahua");
-
-
- cJSON_AddNumberToObject(dataCode, "number", 300);
- // 将datacode (array)结点添加到timecode 对象结点下(同样数组也可以有对象数据, 甚至数组中数据类型也可以不一样,但这样理解上不太好)
- cJSON_AddItemToObject(timeCode, "DATACODE", dataCode);
-
-
- // 最后将JSON数据结构转换为字符串, 并且输出
- char *strForJson = cJSON_Print(JSON_Root);
- printf("json字符串:%s\n", strForJson);
-
-
- // 将字符串存入到文件中
- FILE *FCJ = NULL;
- FILE *FCJ1 = NULL;
-
-
- FCJ = fopen("data.txt", "w");
- FCJ1 = fopen("data1.txt", "w");
-
-
- int i = 0;
-
- for (i = 0; i < strlen(strForJson); ++i)
- {
- fprintf(FCJ, "%c", strForJson[i]);
- fputc(strForJson[i], FCJ1);
- }
-
-
- fclose(FCJ);
- fclose(FCJ1);
-
-
- // 清除结构体
- cJSON_Delete(JSON_Root);
-
-
- return 0;
- }
-
-
输出结果如下:
提示头文件中报unknown type name ‘size_t’错误:
原因及解决方案:
原因在测试c文件中加入了string.h的头文件,并且放在了cJSON.h的后面;
解决:一定要把string.h放在cJSON头文件的前面;
提示找不到pow和floor函数:
解决方案:需要链接math库libm(可以查一下libc相关)
编译语句
- gcc cJson.c CJSONTest.c -o uim -lm
- 最后./uim执行即可;
- #include <stdio.h>
- #include "cJSON.h"
-
-
-
-
- int main()
- {
-
-
- // 定义JSON字符串
- char json_string[]="{\"name\":\"zhuhua\",\
- \"height\":66.666600,\"grade\":100,\"TIMECODE\":{\"Sex\":true,\"datatime\":\"20220811\",\"Judge\":false,\"DATACODE\":[\"English\",\"zhuzhuzhu\",\"huahuahua\",300]}}";//定义JSON字符串
-
- // 将JSON字符串转换成JSON结构体
- cJSON *JSON_ROOT = cJSON_Parse(json_string);
-
-
- // 判断转换是否成功
- if (JSON_ROOT == NULL)
- {
- printf("cjson error.......\n");
- }
- else
- {
- printf("%s\n", cJSON_Print(JSON_ROOT));
- }
-
-
- printf("提取数据\n");
-
-
- // 解析字符串 找key 得value
- char *name = cJSON_GetObjectItem(JSON_ROOT, "name")->valuestring;
- // 打印看一下效果
- printf("%s\n", name);
-
-
- double height = cJSON_GetObjectItem(JSON_ROOT, "height")->valuedouble;
- printf("%lf\n", height);
-
-
- int grade = cJSON_GetObjectItem(JSON_ROOT, "grade")->valueint;
- printf("%d\n", grade);
-
-
- // 对象和数组的接收
- cJSON *obj_timeCode = cJSON_GetObjectItem(JSON_ROOT, "TIMECODE"); // 解析对象
-
-
- cJSON *arr_dataCode = cJSON_GetObjectItem(obj_timeCode, "DATACODE"); // 解析数组 一层一层来
-
-
- int sex = cJSON_GetObjectItem(obj_timeCode, "Sex")->type; // 解析逻辑值————输出逻辑值对应的宏定义数值
- printf("%d\n", sex);
-
-
- char *datatime = cJSON_GetObjectItem(obj_timeCode, "datatime")->valuestring;
- printf("%s\n", datatime);
-
-
- int judge = cJSON_GetObjectItem(obj_timeCode, "Judge")->type; // 解析逻辑值————输出逻辑值对应的宏定义数值
- printf("%d\n", judge);
-
-
- // 数组的处理 先获取数组的成员个数
- int arr_size = cJSON_GetArraySize(arr_dataCode);
- printf("arrsize: %d\n", arr_size);
- int i = 0;
- for (i = 0; i < arr_size - 1; ++i)
- {
- printf("%s\n", cJSON_GetArrayItem(arr_dataCode, i)->valuestring);
- }
- printf("%d\n", cJSON_GetArrayItem(arr_dataCode, arr_size - 1)->valueint);
-
-
- // 清除结构体
- cJSON_Delete(JSON_ROOT);
- return 0;
- }
运行结果如下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。