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