ESP8266學(xué)習(xí)筆記(8)——第三方庫(kù)cJSON使用

一束亏、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ù)

  1. 從給定的JSON字符串中得到cJSON對(duì)象
    cJSON *cJSON_Parse(const char *value)
  2. 從cJSON對(duì)象中獲取有格式的JSON對(duì)象
    char *cJSON_Print(cJSON *item)
  3. 刪除cJSON對(duì)象仔拟,釋放鏈表占用的內(nèi)存空間
    void cJSON_Delete(cJSON *c)
  4. 獲取cJSON對(duì)象數(shù)組成員的個(gè)數(shù)
    int cJSON_GetArraySize(cJSON *array)
  5. 根據(jù)下標(biāo)獲取cJSON對(duì)象數(shù)組中的對(duì)象
    cJSON *cJSON_GetArrayItem(cJSON*array,int item)
  6. 根據(jù)鍵獲取對(duì)應(yīng)的值(cJSON對(duì)象)
    cJSON *cJSON_GetObjectItem(cJSON*object,const char *string)
  7. 新增一個(gè)字符串類型字段到JSON格式的數(shù)據(jù)
    cJSON_AddStringToObject(object,name,s)
  8. 新增一個(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ō)明

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衫樊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子利花,更是在濱河造成了極大的恐慌橡伞,老刑警劉巖盒揉,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異兑徘,居然都是意外死亡刚盈,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)挂脑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)藕漱,“玉大人,你說(shuō)我怎么就攤上這事崭闲±吡” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵刁俭,是天一觀的道長(zhǎng)橄仍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)牍戚,這世上最難降的妖魔是什么侮繁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮如孝,結(jié)果婚禮上宪哩,老公的妹妹穿的比我還像新娘。我一直安慰自己第晰,他們只是感情好锁孟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著茁瘦,像睡著了一般品抽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甜熔,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天圆恤,我揣著相機(jī)與錄音,去河邊找鬼纺非。 笑死哑了,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烧颖。 我是一名探鬼主播弱左,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼炕淮!你這毒婦竟也來(lái)了拆火?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎们镜,沒(méi)想到半個(gè)月后币叹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡模狭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年颈抚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嚼鹉。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贩汉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锚赤,到底是詐尸還是另有隱情匹舞,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布线脚,位于F島的核電站赐稽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏浑侥。R本人自食惡果不足惜姊舵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锭吨。 院中可真熱鬧蠢莺,春花似錦寒匙、人聲如沸零如。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)考蕾。三九已至,卻和暖如春会宪,著一層夾襖步出監(jiān)牢的瞬間肖卧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工掸鹅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塞帐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓巍沙,卻偏偏與公主長(zhǎng)得像葵姥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子句携,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,090評(píng)論 1 32
  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,125評(píng)論 0 3
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,905評(píng)論 2 89
  • 史上最全的iOS面試題及答案 迷途的羔羊--專為路癡量身打造的品牌榔幸。史上最精準(zhǔn)的定位。想迷路都難!閃電更新中......
    南虞閱讀 1,497評(píng)論 0 8
  • 忠誠(chéng) 忠誠(chéng)是作為一名員工應(yīng)該具備的最起碼的品得削咆,也是一種責(zé)任牍疏!對(duì)于一個(gè)忠誠(chéng)的員工,除了做好份內(nèi)的事拨齐,任何時(shí)候鳞陨,都不...
    Lzr_2017閱讀 117評(píng)論 0 2