JSON的簡單介紹以及C語言的JSON庫使用
JSON概述
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 具有自我描述性, 語法簡潔, 易於理解。
JSON語法說明
先來看一個簡單的JSON
1 { 2 "stars": [ 3 { 4 "name": "Faye", 5 "address": "北京" 6 }, 7 { 8 "name": "andy", 9 "address": "香港" 10 }, 11 { 12 "name": "eddie", 13 "address": "臺灣" 14 }, 15 16 ] 17 }
JSON 語法是 JavaScript 對象表示法語法的子集。數據在鍵/值對中;數據由逗號分隔;花括號保存對象, 也稱一個文檔對象;方括號保存數組, 每個數組成員用逗號隔開, 並且每個數組成員可以是文檔對象或者數組或者鍵值對 。
JSON基於兩種結構:
“名稱/值”對的集合(A collection of name/value pairs)。不同的編程語言中,它被理解為對象(object),紀錄(record),結構(struct),字(dictionary),哈希表(hashtable),有鍵列表(keyed list),或者關聯數組 (associative array)。
JSON的三種語法:
鍵/值對 key:value,用半角冒號分割。 比如 "name":"Faye"
文檔對象 JSON對象寫在花括號中,可以包含多個鍵/值對。比如{ "name":"Faye" ,"address":"北京" }。
數組 JSON 數組在方括號中書寫: 數組成員可以是對象,值,也可以是數組(只要有意義)。 {"love": ["乒乓球","高爾夫","斯諾克","羽毛球","LOL","撩妹"]}
附cJSON庫下載地址 https://github.com/DaveGamble/cJSON
cJSON庫在使用的時候只需要如下兩步:將cJSON.c(或者庫文件) 和 cJSON.h添加到項目中即可;如果在命令行中進行鏈接 還需要加上-lm 表示鏈接math庫 .
C語言函數庫寫JSON文件 :
從緩沖區中解析出JSON結構:extern cJSON *cJSON_Parse(const char *value);
解析一塊JSON數據返回cJSON結構, 在使用完之後調用cJSON_Delete函數釋放json對象結構。
將傳入的JSON結構轉化為字符串 :extern char *cJSON_Print(cJSON *item);
可用於輸出到輸出設備, 使用完之後free(char *) 。
將JSON結構所占用的數據空間釋放 :void cJSON_Delete(cJSON *c)
創建一個值類型的數據 :extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
創建一個對象(文檔) :extern cJSON *cJSON_CreateObject(void);
數組創建以及添加 :cJSON *cJSON_CreateIntArray(const int *numbers,int count);
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
JSON嵌套 :
【 向對象中增加鍵值對】 cJSON_AddItemToObject(root, "rows", 值類型數據相關函數());
【 向對象中增加數組】 cJSON_AddItemToObject(root, "rows", cJSON_CreateArray());
【 向數組中增加對象】 cJSON_AddItemToArray(rows, cJSON_CreateObject());
幾個能提高操作效率的宏函數 :#define cJSON_AddNumberToObject(object,name,n) \
cJSON_AddItemToObject(object, name,cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)\
cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
C語言庫函數解析JSON文件 :
根據鍵找json結點 :extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)
判斷是否有key是string的項 如果有返回1 否則返回0 :extern int cJSON_HasObjectItem(cJSON *object,const char *string)
{ return cJSON_GetObjectItem(object,string)?1:0; }
返回數組結點array中成員的個數 :extern int cJSON_GetArraySize(cJSON *array);
根據數組下標index取array數組結點的第index個成員 返回該成員節點 :extern cJSON *cJSON_GetArrayItem(cJSON *array,int index);
遍歷數組 :#define cJSON_ArrayForEach(pos, head) for(pos = (head)->child; pos != NULL; pos = pos->next)
我們先來小試牛刀,編寫一個輸出到屏幕的簡單json結構,代碼1如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include"cJSON.h" 4 5 int main(void) 6 { 7 char *data = "{\"love\":[\"LOL\",\"Go shopping\"]}"; 8 //從緩沖區中解析出JSON結構 9 cJSON * json= cJSON_Parse(data); 10 11 //將傳入的JSON結構轉化為字符串 並打印 12 char *json_data = NULL; 13 printf("data:%s\n",json_data = cJSON_Print(json)); 14 15 free(json_data); 16 //將JSON結構所占用的數據空間釋放 17 cJSON_Delete(json); 18 return 0; 19 }
如下所示編譯程序,執行程序,可以看到屏幕輸出一個簡單的json結構
下面我們在改進一下程序,輸出到屏幕的同時,生成對應的json文件,代碼2如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include"cJSON.h" 5 6 int main(void) 7 { 8 char *char_json = "{\"habit\":\"lol\"}"; 9 //從緩沖區中解析出JSON結構 10 cJSON *json = cJSON_Parse(char_json); 11 //將傳入的JSON結構轉化為字符串 並打印 12 char *buf = NULL; 13 printf("data:%s\n",buf = cJSON_Print(json)); 14 //打開一個exec.json文件,並寫入json內容 15 FILE *fp = fopen("exec.json","w"); 16 fwrite(buf,strlen(buf),1,fp); 17 18 fclose(fp); 19 free(buf); 20 cJSON_Delete(json); 21 return 0; 22 }
如下圖所示進行編譯,執行程序,查看生成的對應的json文件
下面我們生成一個生成一個json結構稍微復雜一點的json文件,代碼3如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include"cJSON.h" 5 6 int main(void) 7 { 8 //創建一個空的文檔(對象) 9 cJSON *json = cJSON_CreateObject(); 10 11 //向文檔中增加一個鍵值對{"name":"王大錘"} 12 cJSON_AddItemToObject(json,"name",cJSON_CreateString("王大錘")); 13 //向文檔中添加一個鍵值對 14 //cJSON_AddItemToObject(json,"age",cJSON_CreateNumber(29)); 15 cJSON_AddNumberToObject(json,"age",29); 16 17 cJSON *array = NULL; 18 cJSON_AddItemToObject(json,"love",array=cJSON_CreateArray()); 19 cJSON_AddItemToArray(array,cJSON_CreateString("LOL")); 20 cJSON_AddItemToArray(array,cJSON_CreateString("NBA")); 21 cJSON_AddItemToArray(array,cJSON_CreateString("Go shopping")); 22 23 cJSON_AddNumberToObject(json,"score",59); 24 cJSON_AddStringToObject(json,"address","beijing"); 25 26 //將json結構格式化到緩沖區 27 char *buf = cJSON_Print(json); 28 //打開文件寫入json內容 29 FILE *fp = fopen("create.json","w"); 30 fwrite(buf,strlen(buf),1,fp); 31 free(buf); 32 fclose(fp); 33 //釋放json結構所占用的內存 34 cJSON_Delete(json); 35 return 0; 36 }
編譯程序,執行程序,查看生成的json文件
下面再來編寫一個,代碼4如下:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include"cJSON.h" 5 6 int main(void) 7 { 8 //先創建空對象 9 cJSON *json = cJSON_CreateObject(); 10 //在對象上添加鍵值對 11 cJSON_AddStringToObject(json,"country","china"); 12 //添加數組 13 cJSON *array = NULL; 14 cJSON_AddItemToObject(json,"stars",array=cJSON_CreateArray()); 15 //在數組上添加對象 16 cJSON *obj = NULL; 17 cJSON_AddItemToArray(array,obj=cJSON_CreateObject()); 18 cJSON_AddItemToObject(obj,"name",cJSON_CreateString("Faye")); 19 cJSON_AddStringToObject(obj,"address","beijing"); 20 //在對象上添加鍵值對 21 cJSON_AddItemToArray(array,obj=cJSON_CreateObject()); 22 cJSON_AddItemToObject(obj,"name",cJSON_CreateString("andy")); 23 cJSON_AddItemToObject(obj,"address",cJSON_CreateString("HK")); 24 25 cJSON_AddItemToArray(array,obj=cJSON_CreateObject()); 26 cJSON_AddStringToObject(obj,"name","eddie"); 27 cJSON_AddStringToObject(obj,"address","TaiWan"); 28 29 //清理工作 30 FILE *fp = fopen("create.json","w"); 31 char *buf = cJSON_Print(json); 32 fwrite(buf,strlen(buf),1,fp); 33 fclose(fp); 34 cJSON_Delete(json); 35 return 0; 36 }
編譯執行程序,效果如下圖所示:
寫了這麽多生成xml的例子,下面我們來一個解析的例子,代碼5如下:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include"cJSON.h" 5 6 int main(void) 7 { 8 char *string = "{\"family\":[\"father\",\"mother\",\"brother\",\"sister\",\"somebody\"]}"; 9 //從緩沖區中解析出JSON結構 10 cJSON *json = cJSON_Parse(string); 11 cJSON *node = NULL; 12 //cJOSN_GetObjectItem 根據key來查找json節點 若果有返回非空 13 node = cJSON_GetObjectItem(json,"family"); 14 if(node == NULL) 15 { 16 printf("family node == NULL\n"); 17 } 18 else 19 { 20 printf("found family node\n"); 21 } 22 node = cJSON_GetObjectItem(json,"famil"); 23 if(node == NULL) 24 { 25 printf("famil node == NULL\n"); 26 } 27 else 28 { 29 printf("found famil node\n"); 30 } 31 //判斷是否有key是string的項 如果有返回1 否則返回0 32 if(1 == cJSON_HasObjectItem(json,"family")) 33 { 34 printf("found family node\n"); 35 } 36 else 37 { 38 printf("not found family node\n"); 39 } 40 if(1 == cJSON_HasObjectItem(json,"famil")) 41 { 42 printf("found famil node\n"); 43 } 44 else 45 { 46 printf("not found famil node\n"); 47 } 48 49 node = cJSON_GetObjectItem(json,"family"); 50 if(node->type == cJSON_Array) 51 { 52 printf("array size is %d",cJSON_GetArraySize(node)); 53 } 54 //非array類型的node 被當做array獲取size的大小是未定義的行為 不要使用 55 cJSON *tnode = NULL; 56 int size = cJSON_GetArraySize(node); 57 int i; 58 for(i=0;i<size;i++) 59 { 60 tnode = cJSON_GetArrayItem(node,i); 61 if(tnode->type == cJSON_String) 62 { 63 printf("value[%d]:%s\n",i,tnode->valuestring); 64 } 65 else 66 { 67 printf("node‘ type is not string\n"); 68 } 69 } 70 71 cJSON_ArrayForEach(tnode,node) 72 { 73 if(tnode->type == cJSON_String) 74 { 75 printf("int forEach: vale:%s\n",tnode->valuestring); 76 } 77 else 78 { 79 printf("node‘s type is not string\n"); 80 } 81 } 82 return 0; 83 }
編譯程序,執行程序,解析出json信息如下圖所示,
關於更多的json學習,可以自己根據提供的cJSON.h cJSON.c進行深入的學習,學無止境,我這裏就介紹到這裏了。
轉自:http://www.cnblogs.com/liunianshiwei/p/6087596.html
JSON的簡單介紹以及C語言的JSON庫使用