C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù))
一、cJSON介紹
cJSON 是一個超輕巧,攜帶方便,單文件,可以作為 ANSI-C 標準的 JSON 解析器,是一個用C語言編寫的簡單好用的JSON解析器;它只包含一個C文件和一個頭文件,可以非常容易集成到自己工程項目中。
并且cJSON是用ANSI C(C89)編寫的,可以兼容所有支持C語言的平臺和編譯器。
cJSON下載地址: https://sourceforge.net/projects/cjson/
cJSON的GitHub倉庫地址:https://github.com/DaveGamble/cJSON

二、JSON簡介、語法介紹
2.1 JSON是什么?
JSON是JavaScript Object Notation(JavaScript對象表示法),是一種輕量級的數(shù)據(jù)交換格式。
JSON主要是用來存儲和交換文本信息,類似XML格式;但是JSON比XML更小、更快,更易解析。
JSON是基于ECMAScript (歐洲計算機協(xié)會制定的js規(guī)范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。
簡潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網(wǎng)絡(luò)傳輸效率。 比如: Web服務(wù)器接口基本都是采用JSON反饋數(shù)據(jù),采用JSON格式字符串來描述符信息。 JSON文件的后綴一般是.json,這個只是為了方便辨識。
簡單的說,JSON就是按照指定格式序列化的字符串,就算不使用任何現(xiàn)成的解析庫,自己也可以按照正常解析字符串的思路去解析;有現(xiàn)成的標準JSON解析庫,那就大大減輕了我們的工作量。
JSON格式的數(shù)據(jù)示例: 這是表示當前時間的JSON字符串
{
"success": "1",
"result": {
"timestamp": "1631849514",
"datetime_1": "2021-09-17 20:31:54",
"datetime_2": "2021年09月17日 20時31分54秒",
"week_1": "5",
"week_2": "星期五",
"week_3": "周五",
"week_4": "Friday"
}
}
JSON格式的數(shù)據(jù)示例: 這是表示未來幾天天氣預(yù)報的json字符串
{
"success": "1",
"result": [
{
"weaid": "1",
"days": "2021-09-17",
"week": "星期五",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "26℃/17℃",
"humidity": "0%/0%",
"weather": "晴",
"weather_icon": "http://api.k780.com/upload/weather/d/0.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
"wind": "北風(fēng)轉(zhuǎn)西南風(fēng)",
"winp": "小于3級",
"temp_high": "26",
"temp_low": "17",
"humi_high": "0",
"humi_low": "0",
"weatid": "1",
"weatid1": "1",
"windid": "8",
"winpid": "0",
"weather_iconid": "0",
"weather_iconid1": "0"
},
{
"weaid": "1",
"days": "2021-09-18",
"week": "星期六",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "25℃/17℃",
"humidity": "0%/0%",
"weather": "多云",
"weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
"wind": "西南風(fēng)",
"winp": "小于3級",
"temp_high": "25",
"temp_low": "17",
"humi_high": "0",
"humi_low": "0",
"weatid": "2",
"weatid1": "2",
"windid": "5",
"winpid": "0",
"weather_iconid": "1",
"weather_iconid1": "1"
},
{
"weaid": "1",
"days": "2021-09-19",
"week": "星期日",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "19℃/15℃",
"humidity": "0%/0%",
"weather": "小雨轉(zhuǎn)中雨",
"weather_icon": "http://api.k780.com/upload/weather/d/7.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/8.gif",
"wind": "西南風(fēng)轉(zhuǎn)北風(fēng)",
"winp": "小于3級轉(zhuǎn)小于3級",
"temp_high": "19",
"temp_low": "15",
"humi_high": "0",
"humi_low": "0",
"weatid": "8",
"weatid1": "9",
"windid": "5",
"winpid": "0",
"weather_iconid": "7",
"weather_iconid1": "8"
},
{
"weaid": "1",
"days": "2021-09-20",
"week": "星期一",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "26℃/16℃",
"humidity": "0%/0%",
"weather": "多云轉(zhuǎn)晴",
"weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
"wind": "北風(fēng)",
"winp": "3-4級轉(zhuǎn)3-4級",
"temp_high": "26",
"temp_low": "16",
"humi_high": "0",
"humi_low": "0",
"weatid": "2",
"weatid1": "1",
"windid": "8",
"winpid": "1",
"weather_iconid": "1",
"weather_iconid1": "0"
},
{
"weaid": "1",
"days": "2021-09-21",
"week": "星期二",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "27℃/16℃",
"humidity": "0%/0%",
"weather": "晴",
"weather_icon": "http://api.k780.com/upload/weather/d/0.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
"wind": "西北風(fēng)轉(zhuǎn)北風(fēng)",
"winp": "小于3級",
"temp_high": "27",
"temp_low": "16",
"humi_high": "0",
"humi_low": "0",
"weatid": "1",
"weatid1": "1",
"windid": "7",
"winpid": "0",
"weather_iconid": "0",
"weather_iconid1": "0"
},
{
"weaid": "1",
"days": "2021-09-22",
"week": "星期三",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "26℃/18℃",
"humidity": "0%/0%",
"weather": "多云",
"weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
"wind": "北風(fēng)轉(zhuǎn)東北風(fēng)",
"winp": "小于3級",
"temp_high": "26",
"temp_low": "18",
"humi_high": "0",
"humi_low": "0",
"weatid": "2",
"weatid1": "2",
"windid": "8",
"winpid": "0",
"weather_iconid": "1",
"weather_iconid1": "1"
},
{
"weaid": "1",
"days": "2021-09-23",
"week": "星期四",
"cityno": "beijing",
"citynm": "北京",
"cityid": "101010100",
"temperature": "24℃/16℃",
"humidity": "0%/0%",
"weather": "多云",
"weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
"weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
"wind": "東北風(fēng)",
"winp": "小于3級",
"temp_high": "24",
"temp_low": "16",
"humi_high": "0",
"humi_low": "0",
"weatid": "2",
"weatid1": "2",
"windid": "1",
"winpid": "0",
"weather_iconid": "1",
"weather_iconid1": "1"
}
]
}
2.2 JSON語法介紹
JSON里就分為兩種結(jié)構(gòu): 對象和數(shù)組,通過這兩種結(jié)構(gòu)可以表示各種復(fù)雜的結(jié)構(gòu)。
JSON語法規(guī)則
1. 大括號 { } 用來保存對象
2. 中括號 [ ] 用來保存數(shù)組,數(shù)組里也可以包含多個對象,對象里又可以包含數(shù)組,可以嵌套
3. JSON的值表示語法: key : value --> "width": 1280
4. 多個數(shù)據(jù)由逗號分隔: {"width": 1920,"height": 1080}
JSON值可以是以下幾種類型:
1. 數(shù)字(整數(shù)或浮點數(shù))
2. 字符串(在雙引號中)
3. 邏輯值(true 或 false)
4. 數(shù)組(在中括號中)
5. 對象(在大括號中)
6. null (空值)
三、cJSON創(chuàng)建簡單JSON數(shù)據(jù)并解析
3.1 新建工程
這是下載下來的cJSON源文件,將它加到自己工程中即可。

我這里使用VS2017建立工程,演示實例。

建好工程之后,將文件添加到工程里:

在VS2017里使用C語言的字符串處理函數(shù)會報錯,提示不安全;
1>d:\linux-share-dir\vs2017\console_cjsontest\console_cjsontest\cjson.c(155): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
解決辦法是:找到【項目屬性】,點擊【C++】里的【預(yù)處理器】,對【預(yù)處理器】進行編輯,在里面加入一段代碼:_CRT_SECURE_NO_WARNINGS。

3.2 創(chuàng)建JSON數(shù)據(jù)
接下來目標是使用cJSON創(chuàng)建出下面這樣一個JSON格式數(shù)據(jù):
{
"text": "我是一個字符串數(shù)據(jù)",
"number": 666,
"state1": false,
"state2": true,
"state3": null
}
示例代碼如下:

#include <iostream>
//因為當前工程使用的是cpp后綴文件,引用C語言的文件需要使用下面的這種方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
int main()
{
//1. 創(chuàng)建cJSON對象
cJSON* root = cJSON_CreateObject();
//2. 創(chuàng)建數(shù)據(jù)
cJSON_AddStringToObject(root, "text","我是一個字符串數(shù)據(jù)");
cJSON_AddNumberToObject(root,"number",666);
cJSON_AddBoolToObject(root, "state1", cJSON_False);
cJSON_AddBoolToObject(root, "state2", cJSON_True);
cJSON_AddNullToObject(root, "state3");
//3. 打印生成的結(jié)果
char *json_data=cJSON_PrintUnformatted(root);
printf("%s\n",json_data);
//4. 釋放空間
cJSON_Delete(root);
return 0;
}

3.3 解析JSON數(shù)據(jù)
#include <iostream>
//因為當前工程使用的是cpp后綴文件,引用C語言的文件需要使用下面的這種方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
//將要解析的JSON數(shù)據(jù).
char data[] =
"{"
"\"text\": \"我是一個字符串數(shù)據(jù)\","
"\"number\" : 666,"
"\"state1\" : false,"
"\"state2\" : true,"
"\"state3\" : null"
"}";
int main()
{
//1. 載入JSON數(shù)據(jù)
cJSON* root = cJSON_Parse(data);
if (root == NULL)return 0;
//2. 解析字段
cJSON* item;
item=cJSON_GetObjectItem(root,"text");
if (item)
{
printf("text=%s\n",item->valuestring);
}
item = cJSON_GetObjectItem(root, "number");
if (item)
{
printf("text=%d\n", item->valueint);
}
item = cJSON_GetObjectItem(root, "state1");
if (item)
{
printf("state1=%d\n", item->valueint);
}
item = cJSON_GetObjectItem(root, "state2");
if (item)
{
printf("state2=%d\n", item->valueint);
}
item = cJSON_GetObjectItem(root, "state3");
if (item)
{
printf("state3=%d\n", item->valueint);
}
//3. 釋放空間
cJSON_Delete(root);
return 0;
}

四、cJSON創(chuàng)建嵌套的對象數(shù)據(jù)
目標: 使用cJSON創(chuàng)建出下面這樣一個JSON格式數(shù)據(jù)
{
"data1": {
"text": "我是一個字符串數(shù)據(jù)1",
"number": 666,
"state1": false,
"state2": true,
"state3": null
},
"data2": {
"text": "我是一個字符串數(shù)據(jù)2",
"number": 666,
"state1": false,
"state2": true,
"state3": null
}
}
4.1 創(chuàng)建json數(shù)據(jù)
#include <iostream>
//因為當前工程使用的是cpp后綴文件,引用C語言的文件需要使用下面的這種方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
int main()
{
//1. 創(chuàng)建cJSON對象
cJSON* root = cJSON_CreateObject();
//2. 創(chuàng)建對象數(shù)據(jù)1
cJSON* item1 = cJSON_CreateObject();
cJSON_AddStringToObject(item1, "text","我是一個字符串數(shù)據(jù)1");
cJSON_AddNumberToObject(item1,"number",666);
cJSON_AddBoolToObject(item1, "state1", cJSON_False);
cJSON_AddBoolToObject(item1, "state2", cJSON_True);
cJSON_AddNullToObject(item1, "state3");
cJSON_AddItemToObject(root, "data1", item1);
//3. 創(chuàng)建對象數(shù)據(jù)2
cJSON* item2 = cJSON_CreateObject();
cJSON_AddStringToObject(item2, "text", "我是一個字符串數(shù)據(jù)2");
cJSON_AddNumberToObject(item2, "number", 666);
cJSON_AddBoolToObject(item2, "state1", cJSON_False);
cJSON_AddBoolToObject(item2, "state2", cJSON_True);
cJSON_AddNullToObject(item2, "state3");
cJSON_AddItemToObject(root, "data2", item2);
//3. 打印生成的結(jié)果
char *json_data=cJSON_PrintUnformatted(root);
printf("%s\n",json_data);
//4. 釋放空間
cJSON_Delete(root);
return 0;
}
4.2 解析JSON數(shù)據(jù)
#include <iostream>
//因為當前工程使用的是cpp后綴文件,引用C語言的文件需要使用下面的這種方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
//將要解析的JSON數(shù)據(jù).
char data[] =
"{"
"\"data1\": {"
"\"text\": \"我是一個字符串數(shù)據(jù)1\","
"\"number\" : 666,"
"\"state1\" : false,"
"\"state2\" : true,"
"\"state3\" : null"
"},"
"\"data2\": {"
"\"text\":\"我是一個字符串數(shù)據(jù)2\","
"\"number\" : 666,"
"\"state1\" : false,"
"\"state2\" : true,"
"\"state3\" : null"
"}"
"}";
int main()
{
//1. 載入JSON數(shù)據(jù)
cJSON* root = cJSON_Parse(data);
if (root == NULL)return 0;
//2. 解析字段
cJSON* item;
item=cJSON_GetObjectItem(root,"data1");
if (item)
{
cJSON *obj;
obj=cJSON_GetObjectItem(item, "text");
if (obj)
{
printf("text=%s\n", obj->valuestring);
}
obj=cJSON_GetObjectItem(item, "number");
if (obj)
{
printf("number=%d\n", obj->valueint);
}
obj = cJSON_GetObjectItem(item, "state1");
if (obj)
{
printf("state1=%d\n", obj->valueint);
}
obj = cJSON_GetObjectItem(item, "state2");
if (obj)
{
printf("state2=%d\n", obj->valueint);
}
obj = cJSON_GetObjectItem(item, "state3");
if (obj)
{
printf("state3=%d\n", obj->valueint);
}
}
item = cJSON_GetObjectItem(root, "data2");
if (item)
{
cJSON *obj;
obj = cJSON_GetObjectItem(item, "text");
if (obj)
{
printf("text=%s\n", obj->valuestring);
}
obj = cJSON_GetObjectItem(item, "number");
if (obj)
{
printf("number=%d\n", obj->valueint);
}
obj = cJSON_GetObjectItem(item, "state1");
if (obj)
{
printf("state1=%d\n", obj->valueint);
}
obj = cJSON_GetObjectItem(item, "state2");
if (obj)
{
printf("state2=%d\n", obj->valueint);
}
obj = cJSON_GetObjectItem(item, "state3");
if (obj)
{
printf("state3=%d\n", obj->valueint);
}
}
//3. 釋放空間
cJSON_Delete(root);
return 0;
}

五、cJSON帶數(shù)組的JSON數(shù)據(jù)
目標: 使用cJSON創(chuàng)建出下面這樣一個JSON格式數(shù)據(jù)
{
"text": [
{
"width": 1280,
"height": 720
},
{
"width": 1920,
"height": 1080
},
{
"width": 3840,
"height": 2160
}
]
}
5.1 創(chuàng)建json數(shù)據(jù)
#include <iostream>
//因為當前工程使用的是cpp后綴文件,引用C語言的文件需要使用下面的這種方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
int main()
{
cJSON *width = NULL;
cJSON *height = NULL;
int i;
const unsigned int resolution_numbers[3][2] = {
{1280, 720},
{1920, 1080},
{3840, 2160}
};
//1. 創(chuàng)建cJSON對象
cJSON* root = cJSON_CreateObject();
//2. 創(chuàng)建數(shù)組對象
cJSON *array = cJSON_CreateArray();
cJSON_AddItemToObject(root, "text", array);
for (i = 0; i < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++i)
{
cJSON *obj = cJSON_CreateObject();
cJSON_AddItemToArray(array, obj);
width = cJSON_CreateNumber(resolution_numbers[i][0]);
cJSON_AddItemToObject(obj, "width", width);
height = cJSON_CreateNumber(resolution_numbers[i][1]);
cJSON_AddItemToObject(obj, "height", height);
}
//3. 打印生成的結(jié)果
char *json_data=cJSON_PrintUnformatted(root);
printf("%s\n",json_data);
//4. 釋放空間
cJSON_Delete(root);
return 0;
}
5.2 解析JSON數(shù)據(jù)
#include <iostream>
//因為當前工程使用的是cpp后綴文件,引用C語言的文件需要使用下面的這種方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
//將要解析的JSON數(shù)據(jù).
char data[] =
"{"
"\"text\": ["
"{"
"\"width\": 1280,"
"\"height\" : 720"
"},"
"{"
"\"width\": 1920,"
"\"height\" : 1080"
"},"
"{"
"\"width\": 3840,"
"\"height\" : 2160"
"}"
"]"
"}";
int main()
{
//1. 載入JSON數(shù)據(jù)
cJSON* root = cJSON_Parse(data);
if (root == NULL)return 0;
//2. 解析字段
cJSON* item;
int i;
item = cJSON_GetObjectItem(root, "text");
if (item)
{
//獲取數(shù)組的大小
int ArraySize = cJSON_GetArraySize(item);
//解析數(shù)組的里的每個成員
for (i = 0; i < ArraySize; i++)
{
//取出數(shù)組下標對象
cJSON *array_item = cJSON_GetArrayItem(item, i);
if (array_item == NULL)continue;
//解析數(shù)據(jù)
cJSON *obj = cJSON_GetObjectItem(array_item, "width");
if (obj)
{
printf("width=%d\n",obj->valueint);
}
obj = cJSON_GetObjectItem(array_item, "height");
if (obj)
{
printf("height=%d\n", obj->valueint);
}
}
}
//3. 釋放空間
cJSON_Delete(root);
return 0;
}

到此這篇關(guān)于C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù))的文章就介紹到這了,更多相關(guān)C++ CJSON使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

