簡介:
????????JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。它基于JavaScript的一個子集,但是JSON是獨立于語言的,這意味著盡管JSON是由JavaScript語法衍生出來的,它可以被任何編程語言讀取和生成。JSON的設計目的是使數據交換既簡單又快速,相對于其他數據交換格式如XML,JSON更加輕巧,這使得它在網絡上傳輸更加高效。對于人類和機器來說,JSON文本的格式都是易于理解的。 管JSON源于JavaScript,但是幾乎所有的編程語言都有解析JSON的庫,這使得JSON成為跨平臺和語言的數據交換的理想格式。
?一、什么是json??
????????JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。它基于JavaScript的一個子集,但是JSON是獨立于語言的,這意味著盡管JSON是由JavaScript語法衍生出來的,它可以被任何編程語言讀取和生成。JSON的設計目的是使數據交換既簡單又快速。
1.1 JSON的特點:
?????? ? 1. 輕量級:相對于其他數據交換格式如XML,JSON更加輕巧,這使得它在網絡上傳輸更加高效。
????? ? 2. 易于閱讀和編寫:對于人類和機器來說,JSON文本的格式都是易于理解的。
? ? ? ? 3.?語言無關性:盡管JSON源于JavaScript,但是幾乎所有的編程語言都有解析JSON的庫,這使得JSON成為跨平臺和語言的數據交換的理想格式。
1.2 JSON的結構:
????????1. 鍵值對集合(在其他語言中可能被實現為對象,記錄,結構,字典,哈希表,有名列表,或者關聯數組)。在JSON中,它們被表示為一個由花括號包圍的對象。每個鍵值對由一個鍵(字符串)和一個值組成,鍵值之間用冒號分隔,鍵值對之間用逗號分隔。
????????2. 有序的值列表(在大多數語言中被實現為數組)。在JSON中,它們被表示為由方括號包圍的數組,數組的元素之間用逗號分隔。
一個簡單的JSON對象示例:
{"name": "John Doe","age": 30,"isEmployed": true,"address": {"street": "123 Main St","city": "Anytown"},"phoneNumbers": ["123-456-7890","987-654-3210"]
}
????????在這個例子中,我們有一個包含五個鍵值對的JSON對象。`name`、`age`和`isEmployed`鍵對應的值是簡單的數據類型(字符串、數字和布爾值)。`address`鍵對應的值是一個嵌套的JSON對象,而`phoneNumbers`鍵對應的值是一個包含字符串的JSON數組。
1.3?基本元素
JSON(JavaScript Object Notation)的語法規則相對簡單,主要包括以下幾個基本元素:
????????1.對象(Object):用花括號 `{}` 表示,包含一組無序的鍵值對。每個鍵值對之間用逗號分隔。鍵必須是字符串,值可以是任意有效的 JSON 數據類型。
{"key1": "value1","key2": "value2","key3": "value3"}
????????2. 數組(Array):用方括號 `[]` 表示,包含一組有序的值。每個值之間用逗號分隔。數組中的值可以是任意有效的 JSON 數據類型。
? ? {"arrayKey": [1, 2, 3, 4]}
????????3. 值(Value):可以是字符串、數字、布爾值、對象、數組或 `null`。這些值可以嵌套在對象或數組中。
? ? {"stringKey": "Hello, JSON!","numberKey": 42,"booleanKey": true,"nullKey": null,"objectKey": {"nestedKey": "nestedValue"},"arrayKey": [1, "two", false, null]}
????????4. 字符串(String): 字符串在JSON中是由雙引號 `" "` 包圍的一系列Unicode字符。字符串用于表示文本數據。
{"name": "John Doe","city": "New York"}
????????5. 數字(Number): 數字可以是整數或者浮點數,直接寫出,不需要加引號。JSON中的數字和大多數編程語言中的表示方法相似。
{"integer": 12,"float": 3.14}
????????6. 布爾值(Boolean): 布爾值表示邏輯實體,只有兩個值,真(`true`)或假(`false`),不需要加引號。
? ? ? ? {"isTrue": true,"isFalse": false}
????????7. null: `null` 在JSON中表示空值或不存在的值。它沒有引號。
? ? ? ? {"emptyValue": null}
具體示例:
{"name": "John Doe","age": 30,"isEmployed": true,"address": {"street": "123 Main St","city": "Anytown"},"phoneNumbers": ["123-456-7890","987-654-3210"]
}
在這個示例中:
????????name、age?和 isEmployed?是簡單的鍵值對,值分別是字符串、數字和布爾值。????????
????????address 是一個嵌套的對象,包含 street?和 city 兩個鍵值對。
????????phoneNumbers??是一個數組,包含兩個字符串值。
????????JSON 的簡潔和易讀特性使它成為數據交換和配置文件的理想選擇。無論是前后端數據傳遞還是存儲配置,JSON 都非常適用。
一個更加復雜的json:t.weather.itboy.net/api/weather/city/101010100
1.4?使用場景:
????????Web開發:JSON廣泛用于前后端之間的數據交換。
????????配置文件:許多應用程序使用JSON格式來存儲配置設置。
????????API和Web服務:許多Web服務使用JSON格式來提供公共API,因為它易于被不同的編程語言讀取和解析。
由于其簡潔、易于理解的結構,JSON已成為Web應用和服務之間交換數據的事實標準。
?二、下載json?
下載鏈接:GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C
解壓后得到這倆個文件?
我們需要將這倆個文件加入到vscode中的C程序文件夾中
三、創建一個json
以下是一個使用 cJSON?創建一個JSON對象的示例代碼:
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main()
{// 創建一個新的JSON對象cJSON *root = cJSON_CreateObject();// 向根對象中添加一個名為"key1"的鍵值對,值為字符串"10"cJSON* key1 = cJSON_AddStringToObject(root,"key1","10");if(key1 != NULL){printf("key:%s value :%s\n",key1->string,key1->valuestring);}// 將JSON對象轉換為字符串格式char *str = cJSON_Print(root); //輸出json字符串// 打印轉換后的JSON字符串printf(str);// 釋放轉換成字符串所使用的內存free(str);// 暫停程序運行,以便查看控制臺輸出system("pause>0");system("pause>0");return 0;
}
????????在這個代碼中,我們創建了一個空的JSON對象 root?
3.1 創建json對象?
// 創建一個新的JSON對象cJSON *root = cJSON_CreateObject();
????????cJSON_CreateObject?函數,這是 cJSON 庫中用來創建一個新的JSON對象的函數。cJSON?是一個在C語言中處理JSON數據的輕量級庫。
如果您想使用這個庫來創建一個JSON對象,您可以按照以下步驟進行:
????????1. 首先,確保已經安裝了 cJSON 庫。
????????2. 在C語言代碼中,包含 cJSON?的頭文件。
????????3. 使用 cJSON_CreateObject?函數來創建一個新的JSON對象。
?3.2 cjson的類型詳解
cjson結構體如下定義:
/* cJSON 結構體: */
typedef struct cJSON
{/* next/prev 允許你在數組/對象鏈中遍歷。或者,使用 GetArraySize/GetArrayItem/GetObjectItem */struct cJSON *next;struct cJSON *prev;/* 數組或對象項將有一個子指針,指向數組/對象中的項鏈。 */struct cJSON *child;/* 項的類型,如上所述。 */int type;/* 項的字符串,如果 type==cJSON_String 和 type == cJSON_Raw */char *valuestring;/* 寫入 valueint 已被棄用,請使用 cJSON_SetNumberValue 代替 */int valueint;/* 項的數字,如果 type==cJSON_Number */double valuedouble;/* 項的名稱字符串,如果此項是對象的子項,或者在對象的子項列表中。 */char *string;
} cJSON;
????????這段代碼定義了一個名為 cJSON?的結構體,這是 cJSON?庫的核心數據結構,它表示一個JSON數據項。每一個 cJSON?結構體可以表示一個JSON對象、數組、字符串、數字或其他的JSON數據類型。
下面是每個成員變量的功能:
????????struct cJSON *next;` 和 `struct cJSON *prev;:這兩個指針分別指向相鄰的JSON數據項,它們使得 cJSON?結構體可以形成一個鏈表,這對于表示一個JSON數組或對象是十分有用的。
????????struct cJSON *child;:如果當前 cJSON?結構體表示一個JSON數組或對象,child 指針會指向一個鏈表,這個鏈表的元素就是數組或對象中的數據項。
????????int type;:這個變量表示當前 cJSON 結構體表示的JSON數據類型,例如,它可能是 cJSON_NULL、cJSON_Number、cJSON_String、cJSON_Array?或 cJSON_Object?等。
????????char *valuestring;:如果當前 cJSON 結構體表示一個JSON字符串,valuestring 就會被設置成那個字符串的值。如果它表示一個原始的未解析的JSON字符串,valuestring?也會被設置成那個字符串的值。
????????int valueint;:這個成員現在已經不建議使用,取而代之的是 cJSON_SetNumberValue?函數來設置JSON數字的值。
????????double valuedouble;:如果當前 cJSON 結構體表示一個JSON數字,valuedouble?就會被設置成那個數字的值。
????????char *string;:如果當前 cJSON 結構體是一個JSON對象中的數據項,string?就會被設置成那個數據項對應的鍵名。
????????我們可以使用 `cJSON` 庫提供的各種函數,如 cJSON_CreateObject、cJSON_AddItemToObject?或 cJSON_GetObjectItem等,來創建、操作和查詢 cJSON?結構體。
3.3 創建鍵值對
????????cJSON_AddStringToObject 。這個函數是 cJSON?庫中的一個函數,用于向一個 JSON 對象中添加一個字符串類型的鍵值對。
cJSON *cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
????????cJSON * const object:這是一個指向 JSON 對象的指針,表示你要往哪個對象中添加鍵值對。
????????const char * const name:這是一個字符串,表示你要添加的鍵的名稱(key)。
????????const char * const string:這是一個字符串,表示你要添加的值(value)。
返回值:
????????cJSON :這個函數返回一個指向新添加的 JSON 元素的指針。這個元素包含了添加的字符串值。如果添加失敗,返回 NULL。
3.4 添加嵌套的JSON對象
????????cJSON_AddItemToObject,來自 cJSON?庫。函數原型應該是:
cJSON_bool cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
????????這個函數的作用是將一個 cJSON?結構(`item`),它可以代表任何類型的JSON數據(如對象、數組、字符串、數字等),添加到另一個 cJSON?對象結構中,并將其與指定的鍵(`string`)相關聯。
參數解釋如下:
????????cJSON *object:這是一個指向目標JSON對象的指針,你會向它添加一個新的元素。
????????const char *string:這是你想要在目標對象中創建的鍵的名稱。
????????cJSON *item:這是一個指向你想要添加的 `cJSON` 元素的指針。
返回值:
????????cJSON_bool:這是一個布爾值,如果成功添加元素則返回 `cJSON_True`,否則返回 `cJSON_False`。
下面是一個使用 `cJSON_AddItemToObject` 函數添加嵌套 JSON 對象的示例:
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main()
{// 創建一個新的JSON對象cJSON *root = cJSON_CreateObject();// 向根對象中添加一個名為"key1"的鍵值對,值為字符串"10"cJSON* key1 = cJSON_AddStringToObject(root,"key1","10");cJSON* last = NULL; // 用于保存上一個添加的鍵值對for(int i = 0; i < 5; i ++){// 創建一個名為"obj1"的子對象cJSON* obj1 = cJSON_CreateObject();// 將子對象添加到根對象中cJSON_AddItemToObject(root,"obj1",obj1); // 向子對象中添加一個名為"key2"的鍵值對,值為字符串"20"cJSON* key2 = cJSON_AddStringToObject(obj1,"key2","20"); // 將子對象添加到根對象中last=key2;}if(key1 != NULL){printf("key:%s value :%s\n",key1->string,key1->valuestring);}// 將JSON對象轉換為字符串格式char *str = cJSON_Print(root); //輸出json字符串// 打印轉換后的JSON字符串printf(str);// 釋放轉換成字符串所使用的內存free(str);// 暫停程序運行,以便查看控制臺輸出system("pause>0");system("pause>0");return 0;
}
????????在這個示例中,我們創建了一個根對象 root?和一個嵌套對象 nested,然后向嵌套對象添加了一個字符串鍵值對,并將嵌套對象作為根對象的一個字段添加進去。最后,我們打印并釋放了相關的內存。
?四、添加數組
4.1?創建數組
cSON_PUBLIC(cSON *) cSON_CreateArray(void);
這個函數聲明創建一個空的JSON數組,并返回一個指向該數組的`cJSON`指針
`cJSON_PUBLIC`是一個宏,用于定義函數的可見性,通常用于導出函數供外部使用。
函數沒有參數,因此調用時不需要傳遞任何參數。返回值是一個指向新創建的JSON數組的指針。你可以使用這個指針來添加元素到數組中,或者將數組添加到其他JSON對象中。
示例用法:
cJSON *array = cJSON_CreateArray();
if (array == NULL) {fprintf(stderr, "錯誤: 無法創建JSON數組。\n");return 1;
}// 現在你可以使用 array 指針來操作這個JSON數組
確保在使用完數組后調用`cJSON_Delete(array)`來釋放內存,以避免內存泄漏。
4.2 添加元素到數組
cJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
這個函數的作用是將一個JSON元素添加到指定的JSON數組中。函數的返回值是一個布爾值,表示添加操作是否成功。如果成功添加元素,返回true
,否則返回false
。
參數說明:
cJSON *array
: 這是一個指向JSON數組的指針,表示你要往哪個數組中添加元素。cJSON *item
: 這是一個指向要添加的JSON元素的指針。可以是任何JSON數據類型,比如字符串、數字、對象等。
我們首先創建了一個空的JSON數組和一個字符串元素,然后將字符串元素添加到數組中。如果添加操作成功,數組將包含這個新添加的元素。如果任何步驟失敗,我們會打印錯誤信息并釋放已分配的內存。
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main()
{// 創建一個JSON對象cJSON *root = cJSON_CreateObject();if (root == NULL) {fprintf(stderr, "錯誤: 無法創建JSON對象。\n");return 1;}// 定義一個整數數組int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 創建一個包含整數數組的JSON數組cJSON *array = cJSON_CreateIntArray(a, 10);if (array == NULL) {fprintf(stderr, "錯誤: 無法創建JSON數組。\n");cJSON_Delete(root);return 1;}// 將JSON數組添加到JSON對象中,鍵名為"array"cJSON_AddItemToObject(root, "array", array);// 將JSON對象轉換為字符串并打印char *json_str = cJSON_Print(root);if (json_str != NULL) {printf("生成的JSON對象: \n%s\n", json_str);free(json_str);} else {fprintf(stderr, "錯誤: 無法打印JSON對象。\n");}// 釋放JSON對象cJSON_Delete(root);// 暫停程序運行,以便查看控制臺輸出system("pause");return 0;
}
- 創建一個JSON對象。
- 定義一個整數數組。
- 創建一個包含整數數組的JSON數組。
- 將JSON數組添加到JSON對象中,鍵名為"array"。
- 將JSON對象轉換為字符串并打印。
- 釋放JSON對象。
- 暫停程序運行,以便查看控制臺輸出。
五、將JSON對象轉為字符串
cSON_Print
函數的作用是將一個 cJSON
元素轉換成字符串,并返回這個字符串的指針。這個函數是用于將 JSON 對象或數組轉換為可讀的字符串格式。
CSON_PUBLIC(char *) cSON_Print(const cSON *item);
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main()
{// 創建一個JSON對象cJSON *root = cJSON_CreateObject();if (root == NULL) {fprintf(stderr, "錯誤: 無法創建JSON對象。\n");return 1;}// 添加一些數據到JSON對象中cJSON_AddNumberToObject(root, "number", 123);cJSON_AddStringToObject(root, "string", "Hello, World!");// 將JSON對象轉換為字符串char *json_str = cJSON_Print(root);if (json_str != NULL) {printf("生成的JSON字符串: \n%s\n", json_str);// 釋放動態分配的字符串內存free(json_str);} else {fprintf(stderr, "錯誤: 無法打印JSON對象。\n");}// 釋放JSON對象cJSON_Delete(root);return 0;
}
我們首先創建了一個 JSON 對象 root
,并向其中添加了一個數字和一個字符串。然后,我們使用 cJSON_Print
函數將這個 JSON 對象轉換為字符串,并打印出來。最后,我們釋放了動態分配的字符串內存和 JSON 對象。