使用cJSON解析JSON字串

2021-08-13 04:06:59 字數 3819 閱讀 1420

一、為何選擇cjson 

我們在使用json格式時,如果只是處理簡單的協議,可以依據json格式,通過對字串 的操作來進行解析與建立。然而隨著協議逐漸複雜起來,經常會遇到一些未考慮周全的地方,需要進一 步的完善解析方法,此時,使用比較完善的json解析庫的需求就提出來了。

基於方便引用的考慮,我們希望這個json解析庫是用c語言實現的。同時,為了避免太 過複雜的c原始碼包含關係,希望最好是乙個c檔案來實現。通過在網路上的查詢,發現cjson是比較符合要 求的。cjson只有乙個c檔案,乙個標頭檔案,包含到專案原始碼中非常方便,而且其實現效率也是非常高 的。

二、cjson的核心結構體

cjson的核心結構體就是乙個cjson,理解了這個結構體,基本上對cjson的使用就有 了個基本概念了。該結構體具體定義如下:

typedef struct cjson cjson;

說明:1、cjson是使用鍊錶來儲存資料的,其訪問方式很像一顆樹。每乙個節點可以有兄弟節點,通過

next/prev指標來查詢,它類似雙向鍊錶;每個節點也可以有孩子節點,通過child指標來訪問,進入下 一層。只有節點是物件或陣列時才可以有孩子節點。

2、type是鍵(key)的型別,一共有7種取值,分別是:false,ture,null,number,string,array, object。

若是number型別,則valueint或valuedouble中儲存著值。若期望的是int,則訪問valueint,若期望的 是double,則訪問valuedouble,可以得到值。

若是string型別的,則valuestring中儲存著值,可以訪問valuestring得到值。

3、string中存放的是這個節點的名字,可理解為key的名稱。

三、解析json格式;

還是在linux下,使用c語言程式設計,先實現讀檔案的功能,然後開始json字串的解析。 我們還是一步步來,先從簡單的開始,萬丈高樓起於平地嘛。  

2,包含cjson的原始碼;

3,解析乙個鍵值對;  

首先是乙個簡單的鍵值對字串,要解析的目標如下:

要進行解析,也就是要分別獲取到鍵與值的內容。我們很容易就能看出鍵為firstname,值為brett,可 是,使用cjson怎麼解析呢? 

對於這個簡單的例子,只需要呼叫cjson的三個介面函式就可以實現解析了,這三個函 數的原型如下:

cjson*cjson_parse(const char *value);

cjson*cjson_getobjectitem(cjson *object,const char *string);

voidcjson_delete(cjson *c); 

下面按解析過程來描述一次:

(1)       首先呼叫cjson_parse()函式,解析json資料報,並按照cjson結構體的結構序列化 整個資料報。使用該函式會通過malloc()函式在記憶體中開闢乙個空間,使用完成需要手動釋放。

cjson*root=cjson_parse(json_string); 

(2)       呼叫cjson_getobjectitem()函式,可從cjson結構體中查詢某個子節點名稱(鍵名 稱),如果查詢成功可把該子節點序列化到cjson結構體中。

cjson*item=cjson_getobjectitem(root,"firstname"); 

(3)       如果需要使用cjson結構體中的內容,可通過cjson結構體中的valueint和 valuestring取出有價值的內容(即鍵的值)

本例子中,我們直接訪問 item->valuestring 就獲取到 "brett" 的內容了。

(4)       通過cjson_delete(),釋放cjson_parse()分配出來的記憶體空間。

cjson_delete(root);

這樣就完成了一次cjson介面呼叫,實現了解析工作。使用起來其實也很簡單的啊, 呵呵。

4,解析乙個結構體;        

接下來,我們來個複雜一點的,解析乙個結構體,要解析的目標如下:

}看起來比乙個鍵值對複雜多了,我們又需要學習新的介面函式了嗎?

答案是不需要!

還是那三個函式就可以了。當然,解析的步驟要複雜一些了,下面我按解析過程來描述 一次: 

(1)根據json串中的物件,我們定義乙個相應的結構體如下:

typedefstruct

person;

具體的對應關係,一目了然,我就不羅嗦了。讓我們直奔主題,解析!     

(2)還是呼叫cjson_parse()函式,解析json資料報。

cjson*root=cjson_parse(json_string); 

(3)呼叫一次cjson_getobjectitem()函式,獲取到物件person。

cjson *object=cjson_getobjectitem(root,"person"); 

(4)對我們剛取出來的物件person,多次呼叫cjson_getobjectitem()函式,來獲取物件的成員。此時 要注意,不同的成員,訪問的方法不一樣:

cjson*item;

personperson;

item=cjson_getobjectitem(object,"firstname");

memcpy(person.firstname,item->valuestring,strlen(item->valuestring));

item=cjson_getobjectitem(object,"lastname");

memcpy(person.lastname,item->valuestring,strlen(item->valuestring));

item=cjson_getobjectitem(object,"email");

memcpy(person.email,item->valuestring,strlen(item->valuestring));

item=cjson_getobjectitem(object,"age");

person.age=item->valueint;

item=cjson_getobjectitem(object,"height");

person.height=item->valuedouble;

這樣,就獲取到了物件的全部內容了。

(5)       通過cjson_delete(),釋放cjson_parse()分配出來的記憶體空間。

cjson_delete(root);

至此,我們就使用cjson介面完成了基於結構體的解析工作。 

5,解析結構體陣列的json串;          

最後,我們來個更複雜一些的,來解析乙個陣列,並且陣列的成員是結構體!要解析 的json串如下:,,

]} 此時,我們真的又需要學習新的介面了,乙個是獲取陣列長度,乙個是取陣列成員, 函式原型如下:

int    cjson_getarraysize(cjson *array);

cjson*cjson_getarrayitem(cjson *array,int item); 

由於前面已經實現了結構體的解析,這裡我們只需要關注下陣列的相關呼叫即可。 

(1)呼叫cjson_parse()函式,解析json資料報。

(2)呼叫一次cjson_getobjectitem()函式,獲取到陣列people。

(3)對我們剛取出來的陣列people,呼叫cjson_getarraysize()函式,來獲取陣列中物件的個數。然

後,多次呼叫cjson_getarrayitem()函式,逐個讀取陣列中物件的內容。

(4)通過cjson_delete(),釋放cjson_parse()分配出來的記憶體空間。

這樣,我們就使用cjson介面完成了結構體陣列的解析工作。

使用cJSON庫解析JSON

cjson是乙個基於c的json解析庫,這個庫非常簡單,只有cjson.c和cjson.h兩個檔案,支援json的解析和封裝,需要呼叫時,只需要 include cjson.h 就可以使用了,json官方 json json字串 這個json物件只有兩個鍵值對,鍵name對應字串andy,鍵age對...

json快速入門(cjson解析)

json是儲存和交換文字資訊的語法,與xml類似。json有兩種結構,分別是陣列和物件 json解析環境 cjson是乙個超輕巧,攜帶方便,單檔案,簡單的可以作為ansi c標準的json解析器,cjson庫包括cjson.h和cjson.c兩個檔案,放入指定目錄直接呼叫就可以了。1.有一對基本的 ...

cJSON對json資料的解析

目標 對下面這種結構的json資料解析 處理步驟 1.將json資料儲存在a.txt內 2.用fopen對資料檔案進行讀取 3.將讀取出的資料流寫入到乙個字串陣列中 4.用cjson parse將字串陣列轉換為json資料物件root 5.對root由外層向內層解析 如下 include inclu...