一束亏、JSON簡(jiǎn)介
JSON (JavaScript Object Notation, JS 對(duì)象簡(jiǎn)譜) 是一種輕量級(jí)的數(shù)據(jù)交換格式铃在。它基于 ECMAScript (歐洲計(jì)算機(jī)協(xié)會(huì)制定的js規(guī)范)的一個(gè)子集阵具,采用完全獨(dú)立于編程語(yǔ)言的文本格式來(lái)存儲(chǔ)和表示數(shù)據(jù)碍遍。
1.1 JSON 語(yǔ)法規(guī)則
在 JS 語(yǔ)言中,一切都是對(duì)象阳液。 因此怕敬,任何支持的類型都可以通過(guò) JSON 來(lái)表示,例如字符串帘皿、數(shù)字东跪、對(duì)象、數(shù)組等鹰溜。但是對(duì)象和數(shù)組是比較特殊且常用的兩種類型:
● 對(duì)象表示為鍵值對(duì)
● 數(shù)據(jù)由逗號(hào)分隔
● 花括號(hào)保存對(duì)象
● 方括號(hào)保存數(shù)組
1.2 JSON 鍵/值對(duì)
JSON 鍵值對(duì)是用來(lái)保存 JS 對(duì)象的一種方式虽填,鍵/值對(duì)組合中的鍵名寫(xiě)在前面并用雙引號(hào) "" 包裹,使用冒號(hào) : 分隔曹动,然后緊接著值:
{"firstName": "Json"}
二斋日、添加cJSON
鏈接:https://pan.baidu.com/s/1t4hn6CHpqK94OJpk4b0Bjw 提取碼:zyjb
將 cJSON.h 添加到工程的 include/ 目錄下
將 cJSON.c 添加到工程的 user/ 目錄下
三、生成JSON數(shù)據(jù)
流程:創(chuàng)建JSON結(jié)構(gòu)體 --> 添加數(shù)據(jù) --> 釋放內(nèi)存
3.1 創(chuàng)建JSON結(jié)構(gòu)體
cJSON *pRoot = cJSON_CreateObject(); // 創(chuàng)建JSON根部結(jié)構(gòu)體
cJSON *pValue = cJSON_CreateObject(); // 創(chuàng)建JSON子葉結(jié)構(gòu)體
3.2 添加字符串類型數(shù)據(jù)
cJSON_AddStringToObject(pRoot,"mac","65:c6:3a:b2:33:c8"); // 添加字符串類型數(shù)據(jù)到根部結(jié)構(gòu)體
cJSON_AddItemToObject(pRoot, "value",pValue);
cJSON_AddStringToObject(pValue,"day","Sunday"); // 添加字符串類型數(shù)據(jù)到子葉結(jié)構(gòu)體
3.3 添加整型數(shù)據(jù)
cJSON_AddNumberToObject(pRoot,"number",2); // 添加整型數(shù)據(jù)到根部結(jié)構(gòu)體
3.4 添加數(shù)組類型數(shù)據(jù)
3.4.1 整型數(shù)組
int hex[5]={51,15,63,22,96};
cJSON *pHex = cJSON_CreateIntArray(hex,5); // 創(chuàng)建整型數(shù)組類型結(jié)構(gòu)體
cJSON_AddItemToObject(pRoot,"hex",pHex); // 添加整型數(shù)組到數(shù)組類型結(jié)構(gòu)體
3.4.2 JSON對(duì)象數(shù)組
cJSON * pArray = cJSON_CreateArray(); // 創(chuàng)建數(shù)組類型結(jié)構(gòu)體
cJSON_AddItemToObject(pRoot,"info",pArray); // 添加數(shù)組到根部結(jié)構(gòu)體
cJSON * pArray_relay = cJSON_CreateObject(); // 創(chuàng)建JSON子葉結(jié)構(gòu)體
cJSON_AddItemToArray(pArray,pArray_relay); // 添加子葉結(jié)構(gòu)體到數(shù)組結(jié)構(gòu)體
cJSON_AddStringToObject(pArray_relay, "relay", "on"); // 添加字符串類型數(shù)據(jù)到子葉結(jié)構(gòu)體
3.5 格式化JSON對(duì)象
char *sendData == cJSON_Print(pRoot); // 從cJSON對(duì)象中獲取有格式的JSON對(duì)象
os_printf("data:%s\n", sendData); // 打印數(shù)據(jù)
生成JSON格式:
{
"mac": "65:c6:3a:b2:33:c8",
"value":
{
"day": "Sunday"
},
"number": 2,
"hex": [51,15,63,22,96],
"info":
[
{
"relay": "on"
}
]
}
3.6 釋放內(nèi)存
cJSON_free((void *) sendData); // 釋放cJSON_Print ()分配出來(lái)的內(nèi)存空間
cJSON_Delete(pRoot); // 釋放cJSON_CreateObject ()分配出來(lái)的內(nèi)存空間
這里說(shuō)明一下墓陈,我們前面調(diào)用了3次cJSON_CreateObject ()恶守,最后只需要針對(duì)root調(diào)用一次釋放即可,因?yàn)楹竺鎰?chuàng)建的對(duì)象也是掛接在root上的贡必。
四兔港、解析JSON數(shù)據(jù)
流程:判斷JSON格式 --> 解析數(shù)據(jù) --> 釋放內(nèi)存
4.1 判斷是否JSON格式
// receiveData是要剖析的數(shù)據(jù)
//首先整體判斷是否為一個(gè)json格式的數(shù)據(jù)
cJSON *pJsonRoot = cJSON_Parse(receiveData);
//如果是否json格式數(shù)據(jù)
if (pJsonRoot !=NULL)
{
···
}
4.2 解析字符串類型數(shù)據(jù)
char bssid[23] = {0};
cJSON *pMacAdress = cJSON_GetObjectItem(pJsonRoot, "mac"); // 解析mac字段字符串內(nèi)容
if (!pMacAdress) return; // 判斷mac字段是否json格式
else
{
if (cJSON_IsString(pMacAdress)) // 判斷mac字段是否string類型
{
strcpy(bssid, pMacAdress->valuestring); // 拷貝內(nèi)容到字符串?dāng)?shù)組
}
}
4.3 解析子葉結(jié)構(gòu)體
char strDay[23] = {0};
cJSON *pValue = cJSON_GetObjectItem(pJsonRoot, "value"); // 解析value字段內(nèi)容
if (!pValue) return; // 判斷value字段是否json格式
else
{
cJSON *pDay = cJSON_GetObjectItem(pValue, "day"); // 解析子節(jié)點(diǎn)pValue的day字段字符串內(nèi)容
if (!pDay) return; // 判斷day字段是否json格式
else
{
if (cJSON_IsString(pDay)) // 判斷day字段是否string類型
{
strcpy(strDay, pDay->valuestring); // 拷貝內(nèi)容到字符串?dāng)?shù)組
}
}
}
4.4 解析整型數(shù)組數(shù)據(jù)
cJSON *pArry = cJSON_GetObjectItem(pJsonRoot, "hex"); // 解析hex字段數(shù)組內(nèi)容
if (!pArry) return; // 判斷hex字段是否json格式
else
{
int arryLength = cJSON_GetArraySize(pArry); // 獲取數(shù)組長(zhǎng)度
int i;
for (i = 0; i < arryLength; i++)
{ // 打印數(shù)組內(nèi)容
os_printf("cJSON_GetArrayItem(pArry, %d)= %d\n",i,cJSON_GetArrayItem(pArry, i)->valueint);
}
}
4.5 解析JSON對(duì)象數(shù)組數(shù)據(jù)
cJSON *pArryInfo = cJSON_GetObjectItem(pJsonRoot, "info"); // 解析info字段數(shù)組內(nèi)容
cJSON *pInfoItem = NULL;
cJSON *pInfoObj = NULL;
char strRelay[23] = {0};
if (!pArryInfo) return; // 判斷info字段是否json格式
else
{
int arryLength = cJSON_GetArraySize(pArryInfo); // 獲取數(shù)組長(zhǎng)度
int i;
for (i = 0; i < arryLength; i++)
{
pInfoItem = cJSON_GetArrayItem(pArryInfo, i); // 獲取數(shù)組中JSON對(duì)象
if(NULL != pInfoItem)
{
pInfoObj = cJSON_GetObjectItem(pInfoItem,"relay");// 解析relay字段字符串內(nèi)容
if(pInfoObj)
{
strcpy(strRelay, pInfoObj->valuestring); // 拷貝內(nèi)容到字符串?dāng)?shù)組
}
}
}
}
解析JSON數(shù)據(jù):
{
"mac": "65:c6:3a:b2:33:c8",
"value":
{
"day": "Sunday"
},
"number": 2,
"hex": [51,15,63,22,96],
"info":
[
{
"relay": "on"
}
]
}
4.6 釋放內(nèi)存
cJSON_Delete(pJsonRoot); // 釋放cJSON_Parse()分配出來(lái)的內(nèi)存空間
五、常用庫(kù)函數(shù)
- 從給定的JSON字符串中得到cJSON對(duì)象
cJSON *cJSON_Parse(const char *value)
- 從cJSON對(duì)象中獲取有格式的JSON對(duì)象
char *cJSON_Print(cJSON *item)
- 刪除cJSON對(duì)象仔拟,釋放鏈表占用的內(nèi)存空間
void cJSON_Delete(cJSON *c)
- 獲取cJSON對(duì)象數(shù)組成員的個(gè)數(shù)
int cJSON_GetArraySize(cJSON *array)
- 根據(jù)下標(biāo)獲取cJSON對(duì)象數(shù)組中的對(duì)象
cJSON *cJSON_GetArrayItem(cJSON*array,int item)
- 根據(jù)鍵獲取對(duì)應(yīng)的值(cJSON對(duì)象)
cJSON *cJSON_GetObjectItem(cJSON*object,const char *string)
- 新增一個(gè)字符串類型字段到JSON格式的數(shù)據(jù)
cJSON_AddStringToObject(object,name,s)
- 新增一個(gè)新的子節(jié)點(diǎn)cJSON到根節(jié)點(diǎn)
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)
? 由 Leung 寫(xiě)于 2019 年 1 月 29 日
? 參考:Esp8266 進(jìn)階之路28 【高級(jí)篇】教你輕松自如使用cJson在樂(lè)鑫 esp8266
cJSON的結(jié)構(gòu)與常用函數(shù)說(shuō)明