當(dāng)前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
cJSON_译(C中的超轻量级JSON解析器)
生活随笔
收集整理的這篇文章主要介紹了
cJSON_译(C中的超轻量级JSON解析器)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
cJSON
- ANSI C中的超輕量級(jí)JSON解析器。
通行證
執(zhí)照
-
版權(quán)所有(c)2009-2017 Dave Gamble和cJSON貢獻(xiàn)者
- 特此免費(fèi)授予獲得此軟件和相關(guān)文檔文件(“軟件”)副本的任何人無限制地處理軟件的權(quán)利,包括但不限于使用,復(fù)制,修改,合并的權(quán)利,發(fā)布,分發(fā),再許可和/或出售本軟件的副本,并允許具有本軟件的個(gè)人遵循以下條件:
- 以上版權(quán)聲明和本許可聲明應(yīng)包含在本軟件的所有副本或大部分內(nèi)容中。
- 本軟件按“原樣”提供,不提供任何形式的明示或暗示的擔(dān)保,包括但不限于對(duì)適銷性,特定目的的適用性和非侵權(quán)性的擔(dān)保。無論是由于軟件,使用或其他方式產(chǎn)生的,與之有關(guān)或與之有關(guān)的合同,侵權(quán)或其他形式的任何索賠,損害或其他責(zé)任,作者或版權(quán)所有者概不負(fù)責(zé)。軟件。
用戶頁
- 歡迎使用cJSON。
- cJSON旨在成為您可以完成工作的最簡(jiǎn)潔的解析器。 它是C的單個(gè)C文件,以及單個(gè)H文件。
- JSON的最佳描述如下:http://www.json.org/就像XML,但沒有冗余的部分。 您可以使用它來傳送數(shù)據(jù),存儲(chǔ)數(shù)據(jù),或者只是在程序上處理數(shù)據(jù)。
- 作為一個(gè)庫文件,cJSON的存在是為了盡可能多地消除繁瑣的工作,但不會(huì)妨礙您的正常工作。 出于實(shí)用的考慮(即忽略事實(shí)),我要說的是您可以在兩種模式之一下使用它:自動(dòng)和手動(dòng)。 讓我們快速瀏覽一下。
- 我從此頁面上提取了一些JSON:http://www.json.org/fatfree.html,該頁面啟發(fā)了我編寫cJSON,這是一個(gè)試圖與JSON本身共享相同哲學(xué)的解析器。 簡(jiǎn)單,操作簡(jiǎn)單,處理準(zhǔn)確。
新建
- 有幾種方法可以將cJSON合并到您的項(xiàng)目中。
復(fù)制源文件
- 因?yàn)檎麄€(gè)庫只有一個(gè)C文件和一個(gè)頭文件,所以您只需將cJSON.h和cJSON.c復(fù)制到項(xiàng)目源并開始使用它。
- cJSON用ANSI C(C89)編寫,以便支持盡可能多的平臺(tái)和編譯器。
編譯
- 使用CMake,cJSON支持完整的構(gòu)建系統(tǒng)。 這樣,您可以獲得最多的功能。 支持版本等于或高于2.8.5的CMake。 推薦使用CMake進(jìn)行樹外構(gòu)建,這意味著將編譯后的文件放在與源文件不同的目錄中。 因此,為了在Unix平臺(tái)上使用CMake構(gòu)建cJSON,創(chuàng)建一個(gè)構(gòu)建目錄并在其中運(yùn)行CMake。
-
這將創(chuàng)建一個(gè)Makefile和一堆其他文件。 然后可以編譯它:
- 并使用make install進(jìn)行安裝。 默認(rèn)情況下,它將頭文件/ usr / local / include / cjson和庫安裝到/ usr / local / lib。 它還會(huì)為pkg-config安裝文件,以使其更易于檢測(cè)和使用CMake的現(xiàn)有安裝。 并安裝CMake配置文件,其他基于CMake的項(xiàng)目可以使用該文件來發(fā)現(xiàn)庫。?
- 您可以使用可傳遞給CMake的不同選項(xiàng)列表來更改構(gòu)建過程。 使用“打開”打開它們,使用“關(guān)閉”關(guān)閉它們:
- 如果要為Linux發(fā)行版打包c(diǎn)JSON,則可能需要采取以下步驟:
- ?在Windows上,CMake通常用于通過在Visual Studio的開發(fā)人員命令提示符中運(yùn)行它來創(chuàng)建Visual Studio解決方案文件,有關(guān)確切步驟,請(qǐng)遵循CMake和Microsoft的官方文檔并使用您選擇的在線搜索引擎。 雖然并非所有選項(xiàng)都可在Windows上使用,但是上面選項(xiàng)的描述通常仍然適用。
生成文件
- 注意:不建議使用此方法。 盡可能使用CMake。 Makefile支持僅限于修復(fù)Bug。如果您沒有可用的CMake,但仍可以使用GNU make。 您可以使用makefile生成cJSON:
- 在帶有源代碼的目錄中運(yùn)行此命令,它將自動(dòng)編譯靜態(tài)和共享庫以及一些測(cè)試程序(而不是完整的測(cè)試套件)。
- 如果需要,可以使用安裝軟件將編譯的庫安裝到系統(tǒng)中。 默認(rèn)情況下,它將在/ usr / local / include / cjson中安裝標(biāo)頭,并在/ usr / local / lib中安裝庫。 但是您可以通過設(shè)置PREFIX和DESTDIR變量來更改此行為:make PREFIX = / usr DESTDIR = temp install。?
?
包含cJSON
- 如果是通過CMake或Makefile安裝的,則可以包含cJSON,如下所示:
?
#include <cjson/cJSON.h>?
數(shù)據(jù)結(jié)構(gòu)
- cJSON使用cJSON結(jié)構(gòu)數(shù)據(jù)類型表示JSON數(shù)據(jù):
-
此類型的項(xiàng)目表示JSON值。 類型以位標(biāo)記的形式存儲(chǔ)在類型中(這意味著您不能僅通過比較類型的值來找出類型)。
-
要檢查項(xiàng)目的類型,請(qǐng)使用相應(yīng)的cJSON_Is ...函數(shù)。 它執(zhí)行NULL檢查,然后進(jìn)行類型檢查,如果該項(xiàng)屬于此類型,則返回布爾值。
類型可以是以下之一:
cJSON_Invalid(檢查cJSON_IsInvalid):表示不包含任何值的無效項(xiàng)目。如果將項(xiàng)目設(shè)置為全零字節(jié),則將自動(dòng)具有此類型。cJSON_False(使用cJSON_IsFalse進(jìn)行檢查):表示錯(cuò)誤的布爾值。您通常還可以使用cJSON_IsBool檢查布爾值。cJSON_True(檢查cJSON_IsTrue):表示真實(shí)的布爾值。您通常還可以使用cJSON_IsBool檢查布爾值。cJSON_NULL(檢查cJSON_IsNull):表示空值。cJSON_Number(檢查cJSON_IsNumber):表示數(shù)字值。該值存儲(chǔ)為valuedouble和valueint中的double。如果數(shù)字超出整數(shù)范圍,則將INT_MAX或INT_MIN用作valueint。cJSON_String(檢查cJSON_IsString):表示一個(gè)字符串值。它以零終止字符串的形式存儲(chǔ)在valuestring中。cJSON_Array(檢查cJSON_IsArray):表示一個(gè)數(shù)組值。這是通過將child指向代表數(shù)組中值的cJSON項(xiàng)的鏈接列表來實(shí)現(xiàn)的。這些元素使用next和prev鏈接在一起,其中第一個(gè)元素具有prev == NULL,最后一個(gè)元素具有next == NULL。cJSON_Object(檢查cJSON_IsObject):表示對(duì)象值。對(duì)象的存儲(chǔ)方式與數(shù)組相同,唯一的區(qū)別是對(duì)象中的項(xiàng)將其鍵存儲(chǔ)在字符串中。cJSON_Raw(與cJSON_IsRaw進(jìn)行檢查):表示以JSON形式存儲(chǔ)的任何類型的JSON,這些字符串以零終止的值數(shù)組形式存在。例如,可以使用它來避免一遍又一遍地打印相同的靜態(tài)JSON以節(jié)省性能。解析時(shí),cJSON永遠(yuǎn)不會(huì)創(chuàng)建此類型。另請(qǐng)注意,cJSON不會(huì)檢查其是否為有效JSON。此外,還有以下兩個(gè)標(biāo)志:
cJSON_IsReference:指定子項(xiàng)指向的項(xiàng)目和/或valuestring不受該項(xiàng)目所有,它僅是引用。 因此,cJSON_Delete和其他函數(shù)將僅取消分配該項(xiàng)目,而不是其子代/值字符串。 cJSON_StringIsConst:這意味著字符串指向常量字符串。 這意味著cJSON_Delete和其他函數(shù)將不會(huì)嘗試取消分配字符串。處理數(shù)據(jù)結(jié)構(gòu)
- 對(duì)于每種值類型,都有一個(gè)cJSON_Create ...函數(shù)可用于創(chuàng)建該類型的項(xiàng)目。 所有這些都將分配一個(gè)cJSON結(jié)構(gòu),以后可以使用cJSON_Delete將其刪除。 請(qǐng)注意,您必須在某些時(shí)候?qū)⑵鋭h除,否則會(huì)發(fā)生內(nèi)存泄漏。 重要提示:如果已經(jīng)將項(xiàng)目添加到數(shù)組或?qū)ο笾?#xff0c;則不能使用cJSON_Delete刪除它。 將其添加到數(shù)組或?qū)ο髮⑥D(zhuǎn)移其所有權(quán),以便在刪除該數(shù)組或?qū)ο髸r(shí)也將其刪除。
基本類型:
使用cJSON_CreateNull創(chuàng)建null布爾值是使用cJSON_CreateTrue,cJSON_CreateFalse或cJSON_CreateBool創(chuàng)建的使用cJSON_CreateNumber創(chuàng)建數(shù)字。 這將同時(shí)設(shè)置valuedouble和valueint。 如果數(shù)字超出整數(shù)范圍,則將INT_MAX或INT_MIN用作valueint字符串是使用cJSON_CreateString(復(fù)制字符串)或cJSON_CreateStringReference(直接指向字符串)創(chuàng)建的。這意味著valueString不會(huì)被cJSON_Delete刪除,并且您要對(duì)字符串的生命期負(fù)責(zé),這對(duì)常量很有用。矩陣
- 您可以使用cJSON_CreateArray創(chuàng)建一個(gè)空數(shù)組。 cJSON_CreateArrayReference可用于創(chuàng)建不“擁有”其內(nèi)容的數(shù)組,因此cJSON_Delete不會(huì)刪除其內(nèi)容。
- 要將項(xiàng)目添加到數(shù)組,請(qǐng)使用cJSON_AddItemToArray將項(xiàng)目追加到末尾。使用cJSON_AddItemReferenceToArray可以將元素添加為對(duì)另一個(gè)項(xiàng)目,數(shù)組或字符串的引用。這意味著cJSON_Delete將不會(huì)刪除該項(xiàng)目的子項(xiàng)或valuestring屬性,因此,如果已經(jīng)在其他地方使用了雙重釋放,則不會(huì)發(fā)生任何雙重釋放。要在中間插入項(xiàng)目,請(qǐng)使用cJSON_InsertItemInArray。它將在基于0的給定索引處插入一個(gè)項(xiàng)目,并將所有現(xiàn)有項(xiàng)目向右移動(dòng)。
- 如果要從給定索引的數(shù)組中取出項(xiàng)目并繼續(xù)使用它,請(qǐng)使用cJSON_DetachItemFromArray,它將返回分離的項(xiàng)目,因此請(qǐng)確保將其分配給指針,否則會(huì)發(fā)生內(nèi)存泄漏。
- 刪除項(xiàng)目是使用cJSON_DeleteItemFromArray完成的。它的工作方式類似于cJSON_DetachItemFromArray,但通過cJSON_Delete刪除了分離的項(xiàng)目。
- 您還可以替換數(shù)組中的項(xiàng)目。使用帶有索引的cJSON_ReplaceItemInArray或使用cJSON_ReplaceItemViaPointer給定了指向元素的指針。如果cJSON_ReplaceItemViaPointer失敗,則將返回0。這在內(nèi)部所做的是分離舊項(xiàng)目,將其刪除,然后將新項(xiàng)目插入其位置。
- 要獲取數(shù)組的大小,請(qǐng)使用cJSON_GetArraySize。使用cJSON_GetArrayItem獲取給定索引處的元素。
- 由于數(shù)組存儲(chǔ)為鏈接列表,因此通過索引對(duì)其進(jìn)行迭代效率不高(O(n2)),因此您可以使用cJSON_ArrayForEach宏以O(shè)(n)時(shí)間復(fù)雜度對(duì)數(shù)組進(jìn)行迭代。
對(duì)象
- 如果要從對(duì)象中取出項(xiàng)目,請(qǐng)使用cJSON_DetachItemFromObjectCaseSensitive,它將返回分離的項(xiàng)目,因此請(qǐng)確保將其分配給指針,否則會(huì)發(fā)生內(nèi)存泄漏。
- 刪除項(xiàng)目是使用cJSON_DeleteItemFromObjectCaseSensitive完成的。它的工作方式類似于cJSON_DetachItemFromObjectCaseSensitive,然后是cJSON_Delete。
- 您也可以在適當(dāng)位置替換對(duì)象中的項(xiàng)目。使用帶有密鑰的cJSON_ReplaceItemInObjectCaseSensitive或帶有給定元素指針的cJSON_ReplaceItemViaPointer。如果cJSON_ReplaceItemViaPointer失敗,則將返回0。這在內(nèi)部所做的是分離舊項(xiàng)目,將其刪除,然后將新項(xiàng)目插入其位置。
- 要獲取對(duì)象的大小,可以使用cJSON_GetArraySize,這是可行的,因?yàn)樵趦?nèi)部將對(duì)象存儲(chǔ)為數(shù)組。
- 如果要訪問對(duì)象中的項(xiàng)目,請(qǐng)使用cJSON_GetObjectItemCaseSensitive。
- 要遍歷對(duì)象,可以使用與數(shù)組相同的方式使用cJSON_ArrayForEach宏。
- cJSON還提供了便捷的幫助器功能,用于快速創(chuàng)建新項(xiàng)目并將其添加到對(duì)象,例如cJSON_AddNullToObject。它們返回指向新項(xiàng)目的指針,如果失敗,則返回NULL。
解析JSON
- 給定一些以零結(jié)尾的字符串的JSON,您可以使用cJSON_Parse對(duì)其進(jìn)行解析。
- 它將解析JSON并分配代表它的cJSON項(xiàng)樹。一旦返回,您將完全負(fù)責(zé)將其與cJSON_Delete一起使用后進(jìn)行分配。
- cJSON_Parse使用的分配器默認(rèn)為malloc且可用,但可以使用cJSON_InitHooks進(jìn)行更改(全局更改)。
- 如果發(fā)生錯(cuò)誤,則可以使用cJSON_GetErrorPtr訪問指向輸入字符串中錯(cuò)誤位置的指針。請(qǐng)注意,盡管這會(huì)在多線程方案中產(chǎn)生競(jìng)爭(zhēng)條件,但在這種情況下,最好將cJSON_ParseWithOpts與return_parse_end結(jié)合使用。默認(rèn)情況下,輸入字符串中已解析的JSON后面的字符將不被視為錯(cuò)誤。
- 如果需要更多選項(xiàng),請(qǐng)使用cJSON_ParseWithOpts(const char * value,const char ** return_parse_end,cJSON_bool require_null_terminated)。 return_parse_end返回一個(gè)指針,指向輸入字符串中JSON的末尾或發(fā)生錯(cuò)誤的位置(從而以線程安全的方式替換cJSON_GetErrorPtr)。如果輸入字符串包含JSON之后的數(shù)據(jù),則require_null_terminated(如果設(shè)置為1)將導(dǎo)致錯(cuò)誤。
打印JSON
- 給定一棵cJSON項(xiàng)目樹,您可以使用cJSON_Print將它們打印為字符串。
- 它將分配一個(gè)字符串并在其中打印樹的JSON表示形式。一旦返回,您將完全負(fù)責(zé)與分配器一起使用后對(duì)其進(jìn)行分配。 (通常是free,取決于cJSON_InitHooks設(shè)置的內(nèi)容)。
- cJSON_Print將使用空格打印以進(jìn)行帶格式打印。如果要打印不帶格式的,請(qǐng)使用cJSON_PrintUnformatted。
- 如果您對(duì)結(jié)果字符串的大小有一個(gè)大概的了解,可以使用cJSON_PrintBuffered(const cJSON * item,int prebuffer,cJSON_bool fmt)。 fmt是一個(gè)布爾值,用于打開和關(guān)閉空白格式。 prebuffer指定要用于打印的第一個(gè)緩沖區(qū)大小。
- cJSON_Print打印當(dāng)前使用的第一個(gè)緩沖區(qū)大小為256個(gè)字節(jié)。一旦打印空間不足,將分配一個(gè)新的緩沖區(qū),并在繼續(xù)打印之前復(fù)制舊緩沖區(qū)。
- 通過使用cJSON_PrintPreallocated(cJSON * item,char * buffer,const int length,const cJSON_bool格式),可以完全避免這些動(dòng)態(tài)緩沖區(qū)分配。它需要一個(gè)指向指針的緩沖區(qū)才能打印到它的長度。如果達(dá)到該長度,則打印將失敗并返回0。如果成功,則返回1。請(qǐng)注意,您應(yīng)該提供比實(shí)際需要更多的5個(gè)字節(jié),因?yàn)閏JSON在估計(jì)提供的內(nèi)存是否足夠時(shí)不是100%準(zhǔn)確的。
例程
- 在此示例中,我們要構(gòu)建并解析以下JSON:
- 讓我們構(gòu)建上面的JSON并將其打印為字符串:
- 另外,我們可以使用cJSON_Add ... ToObject幫助器函數(shù)使我們編寫程序更輕松一些:
解析JSON
遍歷解析幾個(gè)數(shù)組
/* return 1 if the monitor supports full hd, 0 otherwise */ int supports_full_hd(const char * const monitor) {const cJSON *resolution = NULL;const cJSON *resolutions = NULL;const cJSON *name = NULL;int status = 0;cJSON *monitor_json = cJSON_Parse(monitor);if (monitor_json == NULL){const char *error_ptr = cJSON_GetErrorPtr();if (error_ptr != NULL){fprintf(stderr, "Error before: %s\n", error_ptr);}status = 0;goto end;}name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");if (cJSON_IsString(name) && (name->valuestring != NULL)){printf("Checking monitor \"%s\"\n", name->valuestring);}resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions");cJSON_ArrayForEach(resolution, resolutions){cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, "width");cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, "height");if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height)){status = 0;goto end;}if ((width->valuedouble == 1920) && (height->valuedouble == 1080)){status = 1;goto end;}}end:cJSON_Delete(monitor_json);return status; }- 請(qǐng)注意,除了cJSON_Parse的結(jié)果外,沒有NULL檢查,因?yàn)閏JSON_GetObjectItemCaseSensitive已經(jīng)檢查NULL輸入,因此僅傳遞NULL值,如果輸入為NULL,則cJSON_IsNumber和cJSON_IsString返回0。
注意事項(xiàng)
- cJSON不支持包含零字符“ \ 0”或\ u0000的字符串。對(duì)于當(dāng)前的API,這是不可能的,因?yàn)樽址粤憬Y(jié)尾。
- 字符編碼
cJSON僅支持UTF-8編碼的輸入。但是在大多數(shù)情況下,它不會(huì)拒絕無效的UTF-8作為輸入,而只是將其原樣傳播。只要輸入不包含無效的UTF-8,輸出將始終是有效的UTF-8。 - C標(biāo)準(zhǔn)
cJSON用ANSI C(或C89,C90)編寫。如果您的編譯器或C庫未遵循此標(biāo)準(zhǔn),則不能保證正確的行為。
注意:ANSI C不是C ++,因此不應(yīng)使用C ++編譯器進(jìn)行編譯。您可以使用C編譯器對(duì)其進(jìn)行編譯,然后將其與C ++代碼鏈接。盡管可以使用C ++編譯器進(jìn)行編譯,但不能保證正確的行為。 - 浮點(diǎn)數(shù)字
除IEEE754雙精度浮點(diǎn)數(shù)外,cJSON不正式支持任何雙實(shí)現(xiàn)。它可能仍然可以與其他實(shí)現(xiàn)一起使用,但是這些實(shí)現(xiàn)的錯(cuò)誤將被視為無效。
目前,cJSON支持的浮點(diǎn)文字的最大長度為63個(gè)字符。 - 數(shù)組和對(duì)象的深層嵌套
cJSON不支持嵌套太深的數(shù)組和對(duì)象,因?yàn)檫@會(huì)導(dǎo)致堆棧溢出。為了防止這種情況,cJSON將深度限制為CJSON_NESTING_LIMIT,默認(rèn)情況下為1000,但可以在編譯時(shí)更改。 - 線程安全
通常,cJSON不是線程安全的。
但是,在以下情況下它是線程安全的:
永遠(yuǎn)不會(huì)使用cJSON_GetErrorPtr(可以使用cJSON_ParseWithOpts的return_parse_end參數(shù))
在任何線程中使用cJSON之前調(diào)用cJSON_InitHooks。
在返回對(duì)cJSON函數(shù)的所有調(diào)用之前,永遠(yuǎn)不會(huì)調(diào)用setlocale。 - 區(qū)分大小寫
最初創(chuàng)建cJSON時(shí),它不遵循JSON標(biāo)準(zhǔn),并且沒有區(qū)分大寫字母和小寫字母。如果您想要正確的,符合標(biāo)準(zhǔn)的行為,則需要使用CaseSensitive函數(shù)(如果有)。復(fù)制對(duì)象成員 - JSON支持解析和打印JSON,該JSON包含具有多個(gè)具有相同名稱的成員的對(duì)象。但是,cJSON_GetObjectItemCaseSensitive將始終僅返回第一個(gè)。
歡迎使用cJSON!
???? Dave Gamble(原作者)
???? Max Bruckner(現(xiàn)任維護(hù)人員)
???? 和其他cJSON貢獻(xiàn)者
本作者翻譯水平有限,目的是為了認(rèn)真看一遍,順便就翻譯一下,不足之處,歡迎指正哦
總結(jié)
以上是生活随笔為你收集整理的cJSON_译(C中的超轻量级JSON解析器)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电路上的ESR是什么意思?
- 下一篇: 电平转换电路(三极管共射极)