CJSON在C语言中的应用实例讲解

cJSON概念简介:

JSON(JavaScriptObject Notation)是一种轻量级的数据交换格式。可以把JSON的结构理解成无序的、可嵌套的key-value键值对集合,这些key-value键值对是以结构体或数组的形式来组织的。同一级的key-value键值对之间是用一个“,”(逗号)隔开,每个key-value键值对是由一个key后面紧接一个“:”(冒号),冒号后面是这个key对应的value。Key是一个word,由大小写字母、下划线及数字组成,可以由双引号封闭,也可以不加双引号;而value的取值集为:Number、Boolean(true或false)、null、String、Object及Array。

易于人阅读和编写,同时也易于机器解析和生成,已经成为理想的数据交换语言。在C语言中,cJSON一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器,很好的衔接了底层和前端数据的交互处理。

cJSON结构体:

typedefstruct cJSON {

structcJSON *next,*prev;

struct cJSON *child;

int type;

char * valuestring;

int valueint;

double valuedouble;

char *string;

}cJSON;

//cJSON存储的时候是采用链表存储的,其访问方式很像一颗树。每一个节点可以有兄妹节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。

不过,只有节点是对象或数组才可以有孩子节点。

cJSON中的type有7种取值:

#define cJSON_False 0

#define cJSON_True 1

#define cJSON_NULL 2

#define cJSON_Number 3

#define cJSON_String 4

#define cJSON_Array 5

#define cJSON_Object 6

Object:对象,也可理解成一个结构体,是以一对大括号封闭起来的无序的key-value键值对集合,例如:{name:"Susan",age:27,birthday:{year:1984,month:2,day:11}};也可以写成:{"name":"Susan","age":27,"birthday":{"year":1984,"month":2,"day":11}};

Array:数组,JSON的数组是一个以中括号封闭起来的value的集合,即数组内的各个成员的数据类型可以不一样,这一点就跟C/JAVA的数组概念不同了。每个value之间是由一个“,”(逗号)隔开,例如:[123,abc,false,{name:mj}];


代码示例:

1 #include <stdio.h>
2 #include "cJSON.h"
3
4 //使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
5
6 //调用cjson函数创建json串
7 char* createJsonstr()
8 {
9 cJSON * pJsonRoot = NULL;
10 pJsonRoot = cJSON_CreateObject();//新建一个JSON项目
11 if ( NULL == pJsonRoot )
12 {
13 return NULL;
14 }
15 cJSON_AddStringToObject(pJsonRoot,"sayhi","Hello World!!");//在JSON项中添加了字符串
16 cJSON_AddBoolToObject(pJsonRoot,"I`m a man",1);
17 cJSON * pJsonChild = cJSON_CreateObject();//新建一个JSON项目
18 if ( NULL == pJsonChild )
19 {
20 cJSON_Delete(pJsonRoot);
21 return NULL;
22 }
23 cJSON_AddStringToObject(pJsonChild,"name","my name is fengdj");
24 cJSON_AddNumberToObject(pJsonChild,"my age",30);
25 cJSON * pJsonSubChild = cJSON_CreateObject();//新建一个JSON项目
26 if ( NULL == pJsonSubChild)
27 {
28 cJSON_Delete(pJsonRoot);
29 cJSON_Delete(pJsonChild);
30 return NULL;
31 }
32 cJSON_AddStringToObject(pJsonSubChild,"job","I`m a programmer");
33 cJSON_AddFalsetoObject(pJsonSubChild,"baby");
34 cJSON_AddItemToObject(pJsonChild,"sub child item",pJsonSubChild);//把pJsonSubChild项目添加到pJsonChild上。
35 cJSON_AddItemToObject(pJsonRoot,"child item",pJsonChild);//把pJsonChild项目添加到Root项 pJsonRoot
36 char* lpJsonStr = NULL;
37 lpJsonStr = cJSON_Print(pJsonRoot); //CJSON的内存的存储的数据转换为字符串格式
38 cJSON_Delete(pJsonRoot);//因为 child json 和 subchild json 已经被添加到pJsonRoot,所以只需要delete pJsonRoot,
如果你再去delete child 和subchild,将会因重复释放导致程序coredump
39
40 return lpJsonStr;
41 }

42
43 //使用cjson 函数解析json串
44 void parseJsonStr(char* lpJStr)
45 {
46 if( NULL == lpJStr )
47 {
48 return;
49 }
50 cJSON* pJson = cJSON_Parse(lpJStr);//将json串解析后存入cjson内存,并返回cjson实例
51 if( NULL == pJson )
52 {
53 return;
54 }
55 if ( pJson->type == cJSON_Object )
56 {
57 cJSON* pJson1 = cJSON_GetobjectItem(pJson,"sayhi");//从cjson内获取对应key的值
58 if ( NULL == pJson1 )
59 {
60 return;
61 }
62 //pJson1->type
63 printf("%s\n",pJson1->valuestring);
64
65 //+++++
66 cJSON* pNext = pJson1->next; //cJSON_GetobjectItem(pJson,"I`m a man");
67 if ( NULL != pNext )
68 {
69 int iValue = pNext->valueint;
70 printf("+++%d\n",iValue);
71 cJSON* pPre = pNext->prev;
72 if ( NULL != pPre )
73 {
74 printf("++%s\n",pPre->valuestring);
75 }
76 }
77 //++++++
78
79 cJSON* pJson2 = cJSON_GetobjectItem(pJson,"I`m a man");
80 if ( NULL == pJson2 )
81 {
82 return;
83 }
84 //pJson2->type
85 printf("%d\n",pJson2->valueint);

86
87 cJSON* pJson3 = cJSON_GetobjectItem(pJson,"child item");
88 if ( NULL == pJson3 )
89 {
90 return;
91 }
92 if ( pJson3->type == cJSON_Object )
93 {
94 cJSON* pJson31 = cJSON_GetobjectItem(pJson3,"name");
95 if ( NULL == pJson31 )
96 {
97 return;
98 }
99 printf("%s\n",pJson31->valuestring);
100 cJSON* pJson32 = cJSON_GetobjectItem(pJson3,"my age");
101 if ( NULL == pJson32 )
102 {
103 return;
104 }
105 printf("%f\n",pJson32->valuedouble);
106 printf("%d\n",pJson32->valueint);
107 }
108 cJSON* pJson4 = cJSON_GetobjectItem(pJson3,"sub child item");
109 if ( NULL == pJson4 )
110 {
111 return;
112 }
113 if ( pJson4->type == cJSON_Object )
114 {
115 cJSON* pJson41 = cJSON_GetobjectItem(pJson4,"job");
116 if ( NULL == pJson41 )
117 {
118 return;
119 }
120 printf("%s\n",pJson41->valuestring);
121 }
122 }
123 cJSON_Delete(pJson); //程序结束前,回收cjson实例,上述子节点的cjson实例会一并回收
124 }

125
126 //释放json串内存
127 void releaseJsonStr(char *lpJsonStr)
128 {
129 if ( NULL != lpJsonStr )
130 {
131 free(lpJsonStr);
132 }
133 }

135 //创建json数组
136 char* createJsonArray(int iSize)
137 {
138 cJSON * JsonArray = cJSON_CreateArray();
139 if ( NULL == JsonArray )
140 {
141 return NULL;
142 }
143 int i = 0;
144 for ( i=0; i<iSize-2; i++)
145 {
146 cJSON_AddNumberToObject(JsonArray,"hehe",i);
147 }
148 for ( i=iSize; i<iSize+2; i++)
149 {
150 cJSON_AddStringToObject(JsonArray,"he","test");
151 }
152 char * lpArrayJsonStr = cJSON_Print(JsonArray);
153 cJSON_Delete(JsonArray);
154 return lpArrayJsonStr;
155 }
156

157 //解析cjson数组
158 void parseArray(char* lpJsonArrayStr)
159 {
160 if ( NULL == lpJsonArrayStr)
161 {
162 return;
163 }
164 cJSON * pJsonRoot = NULL;
165 pJsonRoot = cJSON_Parse(lpJsonArrayStr);
166 if ( NULL == pJsonRoot )
167 {
168 return;
169 }
170 if ( pJsonRoot->type == cJSON_Array )
171 {
172 int iSize = cJSON_GetArraySize(pJsonRoot);
173 int iIndex = 0;
174 for( ; iIndex<iSize; iIndex++)
175 {
176 cJSON* pItem = cJSON_GetArrayItem(pJsonRoot,iIndex);
177 if ( NULL == pItem )
178 {
179 continue;
180 }
181 if ( pItem->type == cJSON_String )
182 {
183 printf("%s\n",pItem->valuestring);
184 }
185 else if ( pItem->type == cJSON_Number )
186 {
187 int iValue = pItem->valueint;//若你期望的是int,则访问valueint,若期望的是double,则访问valuedouble
188 printf("%d\n",iValue);
189 }
190 }
191 }
192 cJSON_Delete(pJsonRoot);
193 return ;
194 }

195
196 int main()
197 {
198 //创建json 串和解析json串
199 char * lpStr = createJsonstr();
200 if( NULL == lpStr )
201 {
202 return -1;
203 }
204 printf("%s\n",lpStr);
205 parseJsonStr(lpStr);
206 releaseJsonStr(lpStr);
207
208 //创建json数组和解析json数组
209 char * lpArrayJsonStr = createJsonArray(6);
210 if ( NULL == lpArrayJsonStr )
211 {
212 return -1;
213 }
214 printf("%s\n",lpArrayJsonStr);
215 parseArray(lpArrayJsonStr);
216 releaseJsonStr(lpArrayJsonStr);
217 return 0;
218 }
219
220 //CJSON在内存中的存储方式是用链表进行存储的,所以在进行操作的时候,我们可见的部分全部是用指针进行操作的。
221
222

=============================out put===================================

[fengdj@localhost testCJson]$ gcc *.c -lm
[fengdj@localhost testCJson]$ ./a.out
{
"sayhi": "Hello World!!",
"I`m a man": true,
"child item": {
"name": "my name is fengdj",
"my age": 30,
"sub child item": {
"job": "I`m a programmer",
"baby": false
}
}
}
Hello World!!
+++1
++Hello World!!
1
my name is fengdj
30.000000
30
I`m a programmer
[0,1,2,3,"test","test"]
0
1
2
3
test
test

=============================================================================

用法

1、只需在函数includecJSON.h文件,然后和cJSON.c或库文件libcJSON.a一起编译即可使用。

2、具体函数用法详见cJSON.h中注释

相关文章

AJAX是一种基于JavaScript和XML的技术,能够使网页实现异步交...
在网页开发中,我们常常需要通过Ajax从后端获取数据并在页面...
在前端开发中,经常需要循环JSON对象数组进行数据操作。使用...
AJAX(Asynchronous JavaScript and XML)是一种用于创建 We...
AJAX技术被广泛应用于现代Web开发,它可以在无需重新加载页面...
Ajax是一种通过JavaScript和HTTP请求交互的技术,可以实现无...