目錄
一、介紹
1、JSON是什么
2、為什么使用CJSON
3、JSON格式
二、使用CJSON構造JSON
1、創建對象
2、添加字段
3、轉換格式
4、釋放對象
?三、使用CJSON解析JSON
1、解析數據
2、 獲取字段
3、釋放對象
一、介紹
1、JSON是什么
? ? ? ? JSON是什么呢?JSON全稱JavaScript Object Notation,是一種輕量級的數據交換格式,主要用于存儲和交換文本信息。換句話說就是我們用JSON就是為了解析收到的數據和發送對方能夠解析的數據。
? ? ? ? 簡潔和清晰的層次結構使得JSON成為理想的數據交換語言,易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網絡傳輸速率。
2、為什么使用CJSON
? ? ? ?CJSON是一個輕量級、高效、易用的JSON解析庫,適用于C語言。 在做項目開發時,為什么大家都喜歡選擇CJSON來解析JSON字符串呢?CJSON工程文件很簡單,僅一個.c文件和一個.h文件,文件體積很小。除此之外,cJSON 庫通過簡單的 API 提供了高效的 JSON 處理功能。它允許用戶解析 JSON 字符串、創建和修改 JSON 對象、提取字段值,以及將 JSON 對象序列化為字符串。所以cJSON 庫非常適合在資源受限的嵌入式系統中使用。
3、JSON格式
????????對象在花括號 {}
中表示,一組鍵值對組成。鍵是字符串,值可以是字符串、數字、布爾值、數組、對象或 null
。大家可以對照這個示例:
{"name": "xiao xin","age": 21,"is_student": true,"email": "xxxxxxxxxx@qq.com","skills": [ "Python", "C"],"address": {"street": "123 Main St","city": "Anytown","state": "CA","postal_code": "12345"}
}
二、使用CJSON構造JSON
????????在 C 語言中使用 cJSON 庫來構造 JSON 數據非常簡單。接下來我為大家整理了構造JSON常用的幾個函數。
1、創建對象
? ? ? ?我們需要先創建一個空的 cJSON 對象,表示一個 JSON 對象 {}
。
cJSON *cJSON_CreateObject(void);
2、添加字段
? ? ? ? 當創建完對象后,我們需要調用函數往該對象中添加相對應的字段。以下是我整理的常用函數。
(1)添加布爾值
void cJSON_AddBoolToObject(cJSON *object, const char *name, cJSON_bool value);
(2)添加空值
void cJSON_AddNullToObject(cJSON *object, const char *name);
(3)添加JSON數組字段
void cJSON_AddItemToObject(cJSON *object, const char *name, cJSON *item);
(4)添加JSON對象字段
void cJSON_AddItemToObject(cJSON *object, const char *name, cJSON *item);
3、轉換格式
? ? ? ? 最后,我們需要將 cJSON 對象轉換為 JSON 格式的字符串。
char *cJSON_Print(const cJSON *item);
? ? ? ? 該函數會將 cJSON 對象轉換為 JSON 格式的字符串并返回這個字符串的指針。這個函數非常有用,可以幫助將 cJSON 對象構建的 JSON 數據序列化為可讀的文本格式,便于輸出、存儲或傳輸。?
4、釋放對象
????????在使用 cJSON 解析 JSON 數據或構造 JSON 對象之后,我們需要釋放內存,以防止內存泄漏。
void cJSON_Delete(cJSON *c);
??????c
:指向要刪除的 cJSON 對象的指針。
????????給大家一個參考代碼,大家可以自己動手試試看(編譯時注意鏈接CJSON動態庫):
#include <stdio.h>
#include <stdlib.h>
#include <cJSON.h>int main()
{// 創建一個 cJSON 對象,表示一個 JSON 對象 {}cJSON *root = cJSON_CreateObject();// 添加字符串字段cJSON_AddStringToObject(root, "name", "xiao xin");// 添加整數字段cJSON_AddNumberToObject(root, "age", 21);// 創建一個包含技能的 JSON 數組 "skills"cJSON *skillsArray = cJSON_CreateArray();cJSON_AddItemToArray(skillsArray, cJSON_CreateString("Python"));cJSON_AddItemToArray(skillsArray, cJSON_CreateString("C"));cJSON_AddItemToObject(root, "skills", skillsArray);// 添加布爾值字段cJSON_AddBoolToObject(root, "is_student", cJSON_True);// 添加空值字段cJSON_AddNullToObject(root, "notes");// 添加聯系信息 JSON 對象字段cJSON *contactObject = cJSON_CreateObject();cJSON_AddStringToObject(contactObject, "email", "xxxxxxxxxx@qq.com");cJSON_AddStringToObject(contactObject, "phone", "555-555-5555");cJSON_AddItemToObject(root, "contact", contactObject);// 將 cJSON 對象轉換為 JSON 格式的字符串char *json_string = cJSON_Print(root);printf("%s\n", json_string); // 打印生成的 JSON 字符串cJSON_Delete(root); // 釋放 cJSON 對象占用的內存free(json_string); // 釋放 cJSON_Print 分配的內存return 0;
}
運行結果:
?三、使用CJSON解析JSON
?????????在 C 語言中使用 cJSON 庫來解析 JSON 數據非常簡單。接下來我為大家整理了構造JSON常用的幾個函數。
1、解析數據
? ? ? ? 我們需要先將JSON格式的字符串解析成CJSON對象。
cJSON *cJSON_Parse(const char *value);
? ? ? ? 該函數是解析 JSON 數據的關鍵函數,將一個JSON數據包,按照cJSON結構體的結構序列化整個數據包,并在堆中開辟一塊內存存儲cJSON結構體,成功后返回一個指向解析后的 cJSON 對象的指針。
2、 獲取字段
? ? ? ? 接下來我們從一個 cJSON 對象中獲取指定鍵的值。
cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
? ? ? ? 該函數用于獲取JSON字符串字段值,成功返回一個指向cJSON類型的結構體指針。
3、釋放對象
? ? ? ? 和2、4是一樣的,這里就不再重復贅述了。
???????
?????????給大家一個參考代碼,大家可以自己動手試試看(編譯時注意鏈接CJSON動態庫):
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main() {// JSON 字符串const char *json_string = "{""\"name\":\"xiao xin\",""\"age\":21,""\"is_student\":true,""\"email\":\"xxxxx@qq.com\",""\"skills\":[\"Python\",\"C\"],""\"address\":{""\"street\":\"123 Main St\",""\"city\":\"Anytown\",""\"state\":\"CA\",""\"postal_code\":\"12345\"""}""}";// 解析 JSON 字符串cJSON *root = cJSON_Parse(json_string);if (root == NULL) {const char *error_ptr = cJSON_GetErrorPtr();if (error_ptr != NULL) {fprintf(stderr, "Error before: %s\n", error_ptr);}return 1;}// 提取字段cJSON *name = cJSON_GetObjectItem(root, "name");cJSON *age = cJSON_GetObjectItem(root, "age");cJSON *is_student = cJSON_GetObjectItem(root, "is_student");cJSON *email = cJSON_GetObjectItem(root, "email");cJSON *skills = cJSON_GetObjectItem(root, "skills");cJSON *address = cJSON_GetObjectItem(root, "address");// 打印字段if (cJSON_IsString(name) && (name->valuestring != NULL)) {printf("Name: %s\n", name->valuestring);}if (cJSON_IsNumber(age)) {printf("Age: %d\n", age->valueint);}if (cJSON_IsBool(is_student)) {printf("Is student: %s\n", cJSON_IsTrue(is_student) ? "true" : "false");}if (cJSON_IsString(email) && (email->valuestring != NULL)) {printf("Email: %s\n", email->valuestring);}if (cJSON_IsArray(skills)) {printf("Skills:\n");cJSON *skill = NULL;cJSON_ArrayForEach(skill, skills) {if (cJSON_IsString(skill)) {printf(" - %s\n", skill->valuestring);}}}if (cJSON_IsObject(address)) {cJSON *street = cJSON_GetObjectItem(address, "street");cJSON *city = cJSON_GetObjectItem(address, "city");cJSON *state = cJSON_GetObjectItem(address, "state");cJSON *postal_code = cJSON_GetObjectItem(address, "postal_code");if (cJSON_IsString(street) && (street->valuestring != NULL)) {printf("Street: %s\n", street->valuestring);}if (cJSON_IsString(city) && (city->valuestring != NULL)) {printf("City: %s\n", city->valuestring);}if (cJSON_IsString(state) && (state->valuestring != NULL)) {printf("State: %s\n", state->valuestring);}if (cJSON_IsString(postal_code) && (postal_code->valuestring != NULL)) {printf("Postal Code: %s\n", postal_code->valuestring);}}// 釋放 cJSON 對象占用的內存cJSON_Delete(root);return 0;
}
運行結果:
?