您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“cJSON庫有什么用”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“cJSON庫有什么用”這篇文章吧。
cJSON是一個輕量級的json解析庫。使用起來非常簡單,整個庫非常地簡潔,核心功能的實現都在cJSON.c文件,非常適合閱讀源代碼來學習C語言。最近讀完這個庫的源碼,分享自己收獲的一些心得。
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 易于人閱讀和編寫。同時也易于機器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個子集。 JSON采用完全獨立于語言的文本格式,但是也使用了類似于C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成為理想的數據交換語言。
cjson庫github地址:https://github.com/DaveGamble/cJSON
整個庫包含cJSON.h和cJSON.c兩個文件,頭文件定義了一系列的API。這個庫最基本也最重要的功能就是解析一個json字符串,使用的API是cJSON_Parse。cJSON_Parse函數調用了cJSON_ParseWithOpts函數,該函數實現了具體的邏輯。
兩個函數的原型如下:
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
函數接收一段字符串,然后進行解析后返回。解析完返回的是一個cjson結構,cJSON結構的定義如下:
typedef struct cJSON { struct cJSON *next; // 向后指針 struct cJSON *prev; // 向前指針 struct cJSON *child; // 指向子元素,比如子數組或者子對象 int type; // 元素的類型 char *valuestring; // 元素的字符串值,如果type == cJSON_String 或者 type == cJSO_Raw int valueint; // 已廢棄,現在使用cJSON_SetNumberValue設置整型值 double valuedouble; // 元素的整型值,如果type == cJSON_Number char *string; // 表示元素鍵值的值,如果它有子元素的話} cJSON;
json的官網在這里,http://www.json.org
網站首頁描述了json是什么以及它的格式規范,有了規范之后,可以知道json是如何構成的,因此就有了如何解析json數據的方向。
json使用兩種結構構建,對象或者數組。
對象使用{
作開頭,}
作結尾,里邊的每一個元素都是鍵值對的無序集合,鍵名和值使用:
分隔,使用,
分隔每一個元素;數組使用[作開頭,]作結尾,里面的元素都是有序的值組成的集合,且使用,
做分隔符。
每一個值可以是字符串,整型,也可以是true,false,null等常量,還可以是對象或數組,因為json結構是可嵌套的。
因此,我們可以得知:
1、可以根據json的首字母判斷整個json的類型,如果json以'{'
開頭時,就是對象,以'['
開頭時,就是數組,否則就是字符串或者其他常量。
2、如果是對象,那么它的一定有鍵名,先解析它的鍵名,然后解析它的值,解析值的過程與第一步一樣,遞歸解析
3、如果是數組,則逐個解析數組內的元素,直到遇到]
為止,解析數組里面的元素的過程也是與第一步一致,遞歸解析。
這就是根據json官網的定義得出解析json字符串的思路,接下來看看cJSON庫是如何實現的。cJSON_Parse的實現流程圖如下:
cJSON_ParseWithOpts函數里面調用了parse_value,是整個函數的核心實現。
parse_value函數的流程圖如下所示:
可以看到,parse_value是對json值的開頭進行判斷,然后進入相應的分支進行解析,下面對每一個分支進行分析。解析出來的值是保存在cJSON的結構體中,以下命名為item。
如果json值是以'null','true','false',則分別將item的type設置為cJSON_NULL、cJSON_TRUE、cJSON_FALSE。然后繼續解析剩下的json值。
如果遇到"開頭,則說明json值是字符串,就解析它的值,此時只需要拿到兩個"之間的值即可。保存字符串也是一個結構體,需要申請內存,計算長度的過程中,當遇到轉義字符時,需要記錄,因為轉義符不保存。
當遇到數字開頭時,將其后面的數字字符記錄起來,然后轉成整型數字,然后做值的范圍檢查。
解析數組時,為數組的元素創建一個新的json結構體new_item,然后繼續解析數組里面的值,用','判斷下一個元素的位置,得到的值保存到結構體中,并將多個元素用鏈表連接起來。一直解析,直到遇到']'符號。
解析對象的過程與數組的類似,為對象的元素創建一個新的json結構體new_item,然后繼續解析對象里面的值,對象是有鍵值對組成的,因此先得到鍵的值,然后用':'判斷值的位置,進而繼續解析得到值,多個鍵值對之間用','分隔開,最后用鏈表連接起來。一直解析,直到遇到'}'符號。
在解析所有值之前,會調用skip_whitespace函數過濾字符串兩邊的所有空白字符。此處是ASCII碼小于等于32的字符,如:\t、\n。函數如下:
static const unsigned char *skip_whitespace(const unsigned char *in) { while (in && *in && (*in <= 32)) { in++; } return in; }
以上是“cJSON庫有什么用”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。