JSON(JavaScript Object Notation,JavaScript 對(duì)象表示法)是一種輕量級(jí)的數(shù)據(jù)交換格式,由 Douglas Crockford 發(fā)明。它基于 JavaScript 的一個(gè)子集,可以用于在不同平臺(tái)和編程語(yǔ)言之間互相傳遞數(shù)據(jù)。C 語(yǔ)言是一種高效的編程語(yǔ)言,在對(duì) JSON 進(jìn)行解析時(shí)也可以做到高效、靈活和可靠。
C 解析 JSON 的過(guò)程通常可以分為三個(gè)步驟,分別是字符串的解析、token 的構(gòu)建和 token 的解析。字符串的解析是將 JSON 字符串中的內(nèi)容轉(zhuǎn)換成 C 語(yǔ)言中的字符串,并在過(guò)程中進(jìn)行一些處理,如反轉(zhuǎn)義等。token 的構(gòu)建是將解析出的字符串轉(zhuǎn)換成 JSON 對(duì)象,并將其存儲(chǔ)為 token,通常使用 C 中的結(jié)構(gòu)體來(lái)表示。token 的解析是通過(guò)解析構(gòu)建好的 token 對(duì)象來(lái)獲取相應(yīng)的值,如字符串、數(shù)值、真假值等。
typedef struct json_token_s json_token_t; struct json_token_s { json_token_type_t type; /* 類(lèi)型 */ int start; /* 開(kāi)始位置 */ int end; /* 結(jié)束位置 */ json_token_t *parent; /* 父結(jié)點(diǎn) */ json_token_t *child; /* 子結(jié)點(diǎn) */ json_token_t *prev; /* 前結(jié)點(diǎn) */ json_token_t *next; /* 后結(jié)點(diǎn) */ };
在 C 中,我們可以使用一些現(xiàn)成的第三方庫(kù)來(lái)解析 JSON。常用的庫(kù)包括 cJSON、jsmn 等。這些庫(kù)具有不同的特點(diǎn),依據(jù)需求,我們可以選擇最合適的庫(kù)來(lái)使用。以 cJSON 為例,它具有代碼簡(jiǎn)潔、解析速度快等特點(diǎn)。使用 cJSON 來(lái)解析 JSON 的代碼如下:
#include <stdio.h> #include <cjson/cJSON.h> char *json_str = "{ \"name\": \"cJSON\", \"version\": \"1.5.1\" }"; int main(int argc, char **argv) { cJSON *json = cJSON_Parse(json_str); if (json) { cJSON *name = cJSON_GetObjectItemCaseSensitive(json, "name"); printf("name: %s\n", cJSON_GetStringValue(name)); cJSON *version = cJSON_GetObjectItemCaseSensitive(json, "version"); printf("version: %s\n", cJSON_GetStringValue(version)); cJSON_Delete(json); } return 0; }
在上述代碼中,我們使用 cJSON_Parse 函數(shù)來(lái)解析 JSON 字符串,獲取得到的 cJSON 指針指向一個(gè) cJSON 對(duì)象。之后我們就可以根據(jù)自己的需求使用 cJSON 提供的一些函數(shù)來(lái)獲取相應(yīng)的值,如 cJSON_GetObjectItem、cJSON_GetStringValue、cJSON_Delete 等。