CJSON程式設計使用,組裝和解析json格式資料
cJSON,目前來說,就只有兩個檔案,一個cJSON.c 一個cJSON.h檔案。使用的時候,自己建立好一個main.c檔案後,如果是在linux pc上,請使用以下命令進行編譯:
1 gcc -g -Wall *.c -l m
就會預設生成一個 a.out檔案,執行即可。在linux下編譯的時候,注意連結 libm 庫。
整個專案都是以極標準的C來寫的,意思說,可以跨各種平臺使用了。不過,還是有兩三處需要微調一下<針對stm32f103 + rt_thread >。其中修改一下malloc & free & size_t 這三個東西:
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
----------------------------------------
static void *(*cJSON_malloc)(size_t sz) = rt_malloc;
static void (*cJSON_free)(void *ptr) = rt_free;
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
----------------------------------------------------
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = rt_malloc;
cJSON_free = rt_free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:rt_malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:rt_free;
}
複製程式碼
free & malloc就這麼兩個地方要修改一下吧,其中size_t 這個應該是在 .h 檔案修改,主要是rtt的 rt_malloc 和這裡的malloc使用的不同,所以修改了下---不一定非要修改。
所以,這東西說實話,也不存在什麼移植不移植的問題了。很輕鬆的就可以在各個平臺使用了。
例 程
不對json的格式進行說明了,下面直接記下使用方法了。
第一,建立json資料串。這資料串,可能是物件,也可能是陣列,也可能是它們的各種組合,其中再加上一些鍵值對。有一點要先說明:它們的組合,符合父子繼承格式--這也是json資料串的特點。
<1> 建立一個物件,並在這個物件裡面新增一個字串鍵值和一個數字鍵值:
int create_js(void)
{
cJSON *root;
/*create json string root*/
root = cJSON_CreateObject();
if(!root) {
DEBUG("get root faild !\n");
goto EXIT;
}else DEBUG("get root success!\n");
{
cJSON * js_body ;
const char *const body = "body";
cJSON_AddItemToObject(root, body, js_body=cJSON_CreateObject());
cJSON_AddStringToObject(js_body,"name","xiaohui");
cJSON_AddNumberToObject(js_body,"value",600);
{
char *s = cJSON_PrintUnformatted(root);
if(s){
DEBUG("create js string is %s\n",s);
free(s);
}
}
cJSON_Delete(root);
}
return 0;
EXIT:
return -1;
}
int main(int argc, char **argv)
{
create_js();
return 0;
}
執行結果:
1 create js string is {“body”:{“name”:”xiaohui”,”value”:600}}
說明: 建立根物件,使用 cJSON_CreateObject(); 這個API,返回的是一個 cJSON的指標,注意,在這個指標用完了以後,需要手工呼叫 cJSON_Delete(root); 進行記憶體回收。
建立body物件的時候,是在根物件的基礎上進行建立,而插入name 和value的時候,是以body為父節點。需要注意的是 json 格式的資料,雖然也是一個字串的樣子,但這個時候還是無法當成普通的字串進行使用,需要呼叫 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);來將json物件轉換成普通的字串,並且都是以該json物件的根為基點。兩個API的區別即是:一個是沒有格式的:也就是轉換出的字串中間不會有”\n” “\t”之類的東西存在,而cJSON_Print(root);打印出來是人看起來很舒服的格式。僅此而已。
<2> 建立一個數組,並向陣列新增一個字串和一個數字:
1 int create_js(void)
2 {
3 cJSON *root, *js_body;
4 root = cJSON_CreateArray();
5 cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));
6 cJSON_AddItemToArray(root, cJSON_CreateNumber(10));
7 {
8 // char *s = cJSON_Print(root);
9 char *s = cJSON_PrintUnformatted(root);
10 if(s){
11 DEBUG(" %s \n",s);
12 free(s);
13 }
14 }
15 if(root)
16 cJSON_Delete(root);
17
18 return 0;
19 EXIT:
20 return -1;
21 }
22
23 int main(int argc, char **argv)
24 {
25 create_js();
26 return 0;
27 }
執行結果:
1 ["Hello world",10]
<3> 物件裡面包括一個數組,數組裡麵包括物件,物件裡面再新增一個字串和一個數字:
1 int create_js(void)
2 {
3 cJSON *root, *js_body, *js_list;
4 root = cJSON_CreateObject();
5 cJSON_AddItemToObject(root,"body", js_body = cJSON_CreateArray());
6 cJSON_AddItemToArray(js_body, js_list = cJSON_CreateObject());
7 cJSON_AddStringToObject(js_list,"name","xiaohui");
8 cJSON_AddNumberToObject(js_list,"status",100);
9
10 {
11 // char *s = cJSON_Print(root);
12 char *s = cJSON_PrintUnformatted(root);
13 if(s){
14 DEBUG(" %s \n",s);
15 free(s);
16 }
17 }
18 if(root)
19 cJSON_Delete(root);
20
21 return 0;
22 EXIT:
23 return -1;
24 }
25
26 int main(int argc, char **argv)
27 {
28 create_js();
29 return 0;
30 }
執行結果:
1 {"body":[{"name":"xiaohui","status":100}]}
<4>其他組合就依次類推,只要搞清楚父子關係即可。隨便巢狀隨便玩。不再貼了。
<第二, 解析json資料串>
步驟: 1 先將普通的json 字串 處理成 json物件格式。 2 根據關鍵字進行解析,解析的時候,需要根據關鍵字值的型別進行判斷,而這些型別,已經在cJSON.h裡面寫明白了,包括:物件、陣列、普通字串、普通變數等等。
<偷個懶吧,將自己學習的時候用的資料現貼過來,後面休息一下再詳細補充自己在工程中的解析方法>
http://blog.csdn.net/xukai871105/article/details/17094113
http://blog.sina.com.cn/s/blog_a6fb6cc90101ffme.html
<當然,他寫的比較簡潔,還有些可以補充的---其實我已經在上面使用文字進行補充過了。當然,不同的工程,可能解析的方法和側重點並不相同>
或許,是時候把解析的部分補充上來了:
處理流程:
1, 先將普通的json串處理成json物件,也就是所謂的建立json root的過程,只有一行程式碼即可:
cJSON *root;
root = cJSON_Parse(js_string);
ps:需要注意的是,這個root在解析完成後,需要釋放掉,程式碼如下:
if (root)
cJSON_Delete(root);
2,開始拿關鍵字,但如果關鍵字還有父層或者祖層,那就需要先從父層開拿,所謂剝洋蔥是也!
先說沒有父層的:
{“name”:”xiaohong”,”age”:10}
這個字串這樣拿即可:
1 char *s = "{\"name\":\"xiao hong\",\"age\":10}";
2 cJSON *root = cJSON_Parse(s);
3 if(!root) {
4 printf("get root faild !\n");
5 return -1;
6 }
7 cJSON *name = cJSON_GetObjectItem(root, "name");
8 if(!name) {
9 printf("No name !\n");
10 return -1;
11 }
12 printf("name type is %d\n",name->type);
13 printf("name is %s\n",name->valuestring);
14
15 cJSON *age = cJSON_GetObjectItem(root, "age");
16 if(!age) {
17 printf("no age!\n");
18 return -1;
19 }
20 printf("age type is %d\n", age->type);
21 printf("age is %d\n",age->valueint);
顯示結果:
1 name type is 4
2 name is xiao hong
3 age type is 3
4 age is 10
需要注意的是: 上面的type 已經在cJSON.h裡面定義好了,有自己的意義。如果是在嚴格的場所,應該先判定該 item的type,然後再考慮去拿值。
而如果有父層的話,無非就是接著向下拿就是了,稍微修改下前面的demo吧:
處理這串資料吧:
{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}
1 char *s = "{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}";
2 cJSON *root = cJSON_Parse(s);
3 if(!root) {
4 printf("get root faild !\n");
5 return -1;
6 }
7
8 cJSON *js_list = cJSON_GetObjectItem(root, "list");
9 if(!js_list) {
10 printf("no list!\n");
11 return -1;
12 }
13 printf("list type is %d\n",js_list->type);
14
15 cJSON *name = cJSON_GetObjectItem(js_list, "name");
16 if(!name) {
17 printf("No name !\n");
18 return -1;
19 }
20 printf("name type is %d\n",name->type);
21 printf("name is %s\n",name->valuestring);
22
23 cJSON *age = cJSON_GetObjectItem(js_list, "age");
24 if(!age) {
25 printf("no age!\n");
26 return -1;
27 }
28 printf("age type is %d\n", age->type);
29 printf("age is %d\n",age->valueint);
30
31 cJSON *js_other = cJSON_GetObjectItem(root, "other");
32 if(!js_other) {
33 printf("no list!\n");
34 return -1;
35 }
36 printf("list type is %d\n",js_other->type);
37
38 cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
39 if(!js_name) {
40 printf("No name !\n");
41 return -1;
42 }
43 printf("name type is %d\n",js_name->type);
44 printf("name is %s\n",js_name->valuestring);
45
46 if(root)
47 cJSON_Delete(root);
48 return 0;
列印結果:
1 list type is 6
2 name type is 4
3 name is xiao hong
4 age type is 3
5 age is 10
6 list type is 6
7 name type is 4
8 name is hua hua
所謂子子孫孫無窮盡也,按照上面那個方法推下去即可。
3,json 裡陣列怎麼取?
1 {\"list\":[\"name1\",\"name2\"]}
程式碼如下:
複製程式碼
1 int main(int argc, char **argv)
2 {
3 char *s = "{\"list\":[\"name1\",\"name2\"]}";
4 cJSON *root = cJSON_Parse(s);
5 if(!root) {
6 printf("get root faild !\n");
7 return -1;
8 }
9 cJSON *js_list = cJSON_GetObjectItem(root, "list");
10 if(!js_list){
11 printf("no list!\n");
12 return -1;
13 }
14 int array_size = cJSON_GetArraySize(js_list);
15 printf("array size is %d\n",array_size);
16 int i = 0;
17 cJSON *item;
18 for(i=0; i< array_size; i++) {
19 item = cJSON_GetArrayItem(js_list, i);
20 printf("item type is %d\n",item->type);
21 printf("%s\n",item->valuestring);
22 }
23
24 if(root)
25 cJSON_Delete(root);
26 return 0;
27 }
對頭,好簡單的樣子<在別人的庫上使用>
4 如果json數組裡面又搞了物件怎麼辦?
不怕搞物件,就怕這樣搞物件? 無他,就是稍微複雜了一點,全是體力活兒:
<1> 既然是數組裡面,那肯定要先測量陣列的大小,然後根據大小迴圈拿;
<2> 拿到一個數組項,然後把這個項先轉化成普通的json字串,也就是 char *s 能接受的。
<3>再次將這個json字串,轉化成一個json物件
<4> 按照拿普通物件中的東西那樣開幹就行了。
ps:曾經試過直接在陣列項中拿內容,失敗了,不知為何,於是就按照這個4步開幹了。
比如:
1 {\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}
是的.list 是一個數組,數組裡面有兩個物件,那麼程式碼如下:
1 int main(int argc, char **argv)
2 {
3 char *s = "{\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}";
4 cJSON *root = cJSON_Parse(s);
5 if(!root) {
6 printf("get root faild !\n");
7 return -1;
8 }
9 cJSON *js_list = cJSON_GetObjectItem(root, "list");
10 if(!js_list){
11 printf("no list!\n");
12 return -1;
13 }
14 int array_size = cJSON_GetArraySize(js_list);
15 printf("array size is %d\n",array_size);
16 int i = 0;
17 cJSON *item,*it, *js_name, *js_age;
18 char *p = NULL;
19 for(i=0; i< array_size; i++) {
20 item = cJSON_GetArrayItem(js_list, i);
21 if(!item) {
22 //TODO...
23 }
24 p = cJSON_PrintUnformatted(item);
25 it = cJSON_Parse(p);
26 if(!it)
27 continue ;
28 js_name = cJSON_GetObjectItem(it, "name");
29 printf("name is %s\n",js_name->valuestring);
30 js_age = cJSON_GetObjectItem(it, "age");
31 printf("age is %d\n",js_age->valueint);
32
33 }
34
35 if(root)
36 cJSON_Delete(root);
37 return 0;
38 }
按理說,應該釋放下 it 變數才對,但似乎事實不是這樣,僅僅可以釋放根root。
好了,json 解析,無非就是上面的組合了,還能有什麼呢?
解析和封裝都有了,此文結束了。
看這裡:
https://github.com/boyisgood86/learning/tree/master/cjson
good luck !
相關推薦
CJSON程式設計使用,組裝和解析json格式資料
cJSON,目前來說,就只有兩個檔案,一個cJSON.c 一個cJSON.h檔案。使用的時候,自己建立好一個main.c檔案後,如果是在linux pc上,請使用以下命令進行編譯: 1 gcc -g -Wall *.c -l m 就會預設生成一個
C++解析JSON格式資料
因為專案原因需要使用VC6.0解析JSON格式資料,這裡首先介紹VC6.0編譯JSON解析庫的步驟。 首先你必須在http://sourceforge.net/projects/jsoncpp/files/jsoncpp/下載jsoncpp的原始碼(.cpp/.h/.inl檔案),然後包含到你
SpringBoot+Jpa 在MySql中自動生成時間和返回json格式資料時間格式配置
先說資料時間格式的設定 有兩種 一種是:可以在apllication.property加入下面配置就可以 #時間戳統一轉換 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=
使用jQuery傳送POST,Ajax請求返回JSON格式資料
問題:使用jQuery POST提交資料到PHP檔案, PHP返回的json_encode後的陣列資料,但jQuery接收到的資料不能解析為JSON物件,而是字串{"code":-1,"msg":"12
java傳送http的get、post請求,使用fastjson傳json格式資料(application/json)
GET方式: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import ja
【php】jquery中$.get實現解析json格式資料及jsonp跨域
一直以來都是寫ajax都是使用$.getjson這個方法,主要圖的就是跨域方便,當然跨域有時候也會帶來不安全的隱患,現在專案中是$get,例子中基本上返回的是string格式,自己寫getjson寫習慣,想返回json格式的。下面就介紹三種實現json格式返回的方法。
java解析json格式資料
有時候可能會用到json格式進行資料的傳輸,那麼怎麼把接收到的資料解析出來呢? 下面介紹兩種解析json資料的方法: 1、通過谷歌的Gson來進行解析: json資料:sTotalString = {"message":"success","result":[{
golang解析json格式資料
友情推廣 json簡介 JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。 常見樣式1 { "id": 1, "name": "bill" } 這個json格式資料中,包含了2個欄位,一個
Android訪問網路系列之--服務端返回XML或JSON格式資料,Android 進行解析並顯示
例子說明:使用者通過訪問web資源的最新電影資訊,伺服器端生成XML或JSON格式資料,返回Android客戶端進行顯示。 此案例開發需要兩個方面 WEB開發和android開發. 一.web開發相對比較簡單,只是模擬一下 相關程式碼如下: 1.實體Bean package ygc.yxb.domain
Android訪問網路:服務端返回XML或JSON格式資料,Android 進行解析並使用ListView顯示
剛剛入門學習了Android的ListView,也是看了傳智播客黎活明老師的視訊學習了,但是一直執行不了,還報錯了。報的錯誤是:at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.jav
fastjson生成和解析json資料,序列化和反序列化資料
publicstaticfinalObject parse(String text);//把JSON文字parse為JSONObject或者JSONArraypublicstaticfinalJSONObject parseObject(String text);// 把JSON文字parse成JSONObj
分別講解gson和fastjson解析json格式
1、Gson講解 gson是谷歌開發支援的,谷歌GSON這個Java類庫可以把Java物件轉換成JSON,也可以把JSON字串轉換成一個相等的Java物件。 * 伺服器端將資料轉換成json字串 在很多的時候,需要客戶端上傳json格式給伺服器,如果你自己去拼湊js
安卓開發之解析XML和JSON格式資料
參考書作者:郭霖我會將所學的知識簡單記錄下來以便於大家快速查閱資料,另外郭霖大俠沒有提到的東西我也會作出補充我們通常情況下,每個需要訪問網路的應用程式都會有一個自己的伺服器,我們可以向伺服器提交資料,也可以從伺服器上獲取資料。在網路上傳輸資料時最常用的格式用兩種:XML和JS
使用JSONObject生成和解析json
-i 引入 detail .so map對象 com cti name ber 使用JSONObject生成和解析json 1. json數據類型 類型描述 Number 數字型 String 字符串型 Boolean 布爾型 Array 數組
在VS2013下編譯json-c庫,並簡單生成json格式數據
ray string 數組 ring std bject sub obj ++ #include "stdafx.h"#include "json-c/json.h" int _tmain(int argc, _TCHAR* argv[]){ // 正常的json格式 js
PHP記錄和讀取JSON格式日誌文件
contents 日誌文件 轉換 ret abs 轉換成 情況 查找 $max 我們有時需要記錄用戶或者後端的某個操作事件的運行情況,可以使用後端語言如PHP將操作結果記錄到日誌文件中,方便測試和查找問題。尤其是這些在後端運行的而前端不能直接看到運行結果的,那麽就可以用日誌
Swift: 用Alamofire做http請求,用ObjectMapper解析JSON
not tis ati obj 有意 objects 映射 loaddata api 演示樣例代碼看最後。 跟不上時代的人突然間走在了時代的前列,果然有別樣的風景
頁面訪問伺服器返回json格式資料太大,導致資料不全被截斷,無法展示
問題:頁面展示呼叫查詢方法查詢全部資料的時候一直顯示loading。。。,開啟偵錯程式顯示 Failed to load resource: net::ERR_SPDY_PROTOCOL_ERROR,而少部分查詢則正常顯示。 因為資料中有圖片轉成的二進位制陣列,資料比較長,由此懷疑
c語言建立和解析json資料
之前一篇有說到使用lincurl庫獲取網頁資料,那麼問題來了,當我們獲取到的資料大多是json的格式,應該怎麼解析出我們需要的欄位呢?下面我們使用json-glib庫來對json資料進行建立和解析。 #include<json-glib/json-glib.h> #include
typeScript(7)--ts面向物件程式設計,繼承和重寫
類的繼承 在使用TypeScript這門語言時,一個最重要基本功就是面向物件程式設計,那對類的擴充套件就變的格外重要,擴充套件經常使用的手段就是繼承。 繼承:允許我們建立一個類(子類),從已有的類(父類)上繼承所有的屬性和方法,子類可以新建父類中沒有的屬性和方法。