![在stm32上使用cJSON解析JSON字符串全套_第1頁](http://file4.renrendoc.com/view10/M02/28/0C/wKhkGWV7p0OALYzRAAFqB6o_E0c081.jpg)
![在stm32上使用cJSON解析JSON字符串全套_第2頁](http://file4.renrendoc.com/view10/M02/28/0C/wKhkGWV7p0OALYzRAAFqB6o_E0c0812.jpg)
![在stm32上使用cJSON解析JSON字符串全套_第3頁](http://file4.renrendoc.com/view10/M02/28/0C/wKhkGWV7p0OALYzRAAFqB6o_E0c0813.jpg)
![在stm32上使用cJSON解析JSON字符串全套_第4頁](http://file4.renrendoc.com/view10/M02/28/0C/wKhkGWV7p0OALYzRAAFqB6o_E0c0814.jpg)
![在stm32上使用cJSON解析JSON字符串全套_第5頁](http://file4.renrendoc.com/view10/M02/28/0C/wKhkGWV7p0OALYzRAAFqB6o_E0c0815.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
在stm32上使用cJSON解析JSON字符串一、為何選擇cJSON我們在使用JSON格式時,如果只是處理簡單的協(xié)議,可以依據(jù)JSON格式,通過對字符串的操作來進(jìn)行解析與創(chuàng)建。然而隨著協(xié)議逐漸復(fù)雜起來,經(jīng)常會遇到一些未考慮周全的地方,需要進(jìn)一步的完善解析方法,此時,使用比較完善的JSON解析庫的需求就提出來了。二、cJSON的核心結(jié)構(gòu)體cJSON的核心結(jié)構(gòu)體就是一個cJSON,理解了這個結(jié)構(gòu)體,基本上對cJSON的使用就有了個基本概念了。該結(jié)構(gòu)體具體定義如下:typedefstructcJSON{structcJSON*next,*prev;/*遍歷數(shù)組或?qū)ο箧湹那跋蚧蚝笙蜴湵碇羔?/structcJSON*child;/*數(shù)組或?qū)ο蟮暮⒆庸?jié)點(diǎn)*/inttype;/*key的類型*/char*valuestring;/*字符串值*/intvalueint;/*整數(shù)值*/doublevaluedouble;/*浮點(diǎn)數(shù)值*/char*string;/*key的名字*/}cJSON;說明:1、cJSON是使用鏈表來存儲數(shù)據(jù)的,其訪問方式很像一顆樹。每一個節(jié)點(diǎn)可以有兄弟節(jié)點(diǎn),通過next/prev指針來查找,它類似雙向鏈表;每個節(jié)點(diǎn)也可以有孩子節(jié)點(diǎn),通過child指針來訪問,進(jìn)入下一層。只有節(jié)點(diǎn)是對象或數(shù)組時才可以有孩子節(jié)點(diǎn)。2、type是鍵(key)的類型,一共有7種取值,分別是:False,Ture,NULL,Number,String,Array,Object。若是Number類型,則valueint或valuedouble中存儲著值。若期望的是int,則訪問valueint,若期望的是double,則訪問valuedouble,可以得到值。若是String類型的,則valuestring中存儲著值,可以訪問valuestring得到值。3、string中存放的是這個節(jié)點(diǎn)的名字,可理解為key的名稱。三、解析JSON格式;3,解析一個鍵值對;首先是一個簡單的鍵值對字符串,要解析的目標(biāo)如下:{"firstName":"Brett"}要進(jìn)行解析,也就是要分別獲取到鍵與值的內(nèi)容。我們很容易就能看出鍵為firstName,值為Brett,可是,使用cJSON怎么解析呢?對于這個簡單的例子,只需要調(diào)用cJSON的三個接口函數(shù)就可以實(shí)現(xiàn)解析了,這三個函數(shù)的原型如下:cJSON*cJSON_Parse(constchar*value);cJSON*cJSON_GetObjectItem(cJSON*object,constchar*string);voidcJSON_Delete(cJSON*c);下面按解析過程來描述一次:(1)首先調(diào)用cJSON_Parse()函數(shù),解析JSON數(shù)據(jù)包,并按照cJSON結(jié)構(gòu)體的結(jié)構(gòu)序列化整個數(shù)據(jù)包。使用該函數(shù)會通過malloc()函數(shù)在內(nèi)存中開辟一個空間,使用完成需要手動釋放。cJSON*root=cJSON_Parse(json_string);(2)調(diào)用cJSON_GetObjectItem()函數(shù),可從cJSON結(jié)構(gòu)體中查找某個子節(jié)點(diǎn)名稱(鍵名稱),如果查找成功可把該子節(jié)點(diǎn)序列化到cJSON結(jié)構(gòu)體中。cJSON*item=cJSON_GetObjectItem(root,"firstName");(3)如果需要使用cJSON結(jié)構(gòu)體中的內(nèi)容,可通過cJSON結(jié)構(gòu)體中的valueint和valuestring取出有價值的內(nèi)容(即鍵的值)本例子中,我們直接訪問item->valuestring就獲取到"Brett"的內(nèi)容了。(4)通過cJSON_Delete(),釋放cJSON_Parse()分配出來的內(nèi)存空間。cJSON_Delete(root);這樣就完成了一次cJSON接口調(diào)用,實(shí)現(xiàn)了解析工作。使用起來其實(shí)也很簡單的啊,呵呵。4,解析一個結(jié)構(gòu)體;接下來,我們來個復(fù)雜一點(diǎn)的,解析一個結(jié)構(gòu)體,要解析的目標(biāo)如下:{"person":{"firstName":"z","lastName":"jadena","email":"jadena@126.com","age":8,"height":1.17}}看起來比一個鍵值對復(fù)雜多了,我們又需要學(xué)習(xí)新的接口函數(shù)了嗎?答案是不需要!還是那三個函數(shù)就可以了。當(dāng)然,解析的步驟要復(fù)雜一些了,下面我按解析過程來描述一次:(1)根據(jù)JSON串中的對象,我們定義一個相應(yīng)的結(jié)構(gòu)體如下:typedefstruct{charfirstName[32];charlastName[32];charemail[64];intage;floatheight;}PERSON;具體的對應(yīng)關(guān)系,一目了然,我就不羅嗦了。讓我們直奔主題,解析?。?)還是調(diào)用cJSON_Parse()函數(shù),解析JSON數(shù)據(jù)包。cJSON*root=cJSON_Parse(json_string);(3)調(diào)用一次cJSON_GetObjectItem()函數(shù),獲取到對象person。cJSON*object=cJSON_GetObjectItem(root,"person");(4)對我們剛?cè)〕鰜淼膶ο髉erson,多次調(diào)用cJSON_GetObjectItem()函數(shù),來獲取對象的成員。此時要注意,不同的成員,訪問的方法不一樣:cJSON*item;PERSONperson;item=cJSON_GetObjectItem(object,"firstName");memcpy(person.firstName,item->valuestring,strlen(item->valuestring));item=cJSON_GetObjectItem(object,"lastName");memcpy(person.lastName,item->valuestring,strlen(item->valuestring));item=cJSON_GetObjectItem(object,"email");memcpy(person.email,item->valuestring,strlen(item->valuestring));item=cJSON_GetObjectItem(object,"age");person.age=item->valueint;item=cJSON_GetObjectItem(object,"height");person.height=item->valuedouble;這樣,就獲取到了對象的全部內(nèi)容了。(5)通過cJSON_Delete(),釋放cJSON_Parse()分配出來的內(nèi)存空間。cJSON_Delete(root);至此,我們就使用cJSON接口完成了基于結(jié)構(gòu)體的解析工作。5,解析結(jié)構(gòu)體數(shù)組的JSON串;最后,我們來個更復(fù)雜一些的,來解析一個數(shù)組,并且數(shù)組的成員是結(jié)構(gòu)體!要解析的JSON串如下:{"people":[{"firstName":"z","lastName":"Jason","email":"bbbb@126.com","height":1.67},{"lastName":"jadena","email":"jadena@126.com","age":8,"height":1.17},{"email":"cccc@126.com","firstName":"z","lastName":"Juliet","age":36,"height":1.55}]}此時,我們真的又需要學(xué)習(xí)新的接口了,一個是獲取數(shù)組長度,一個是取數(shù)組成員,函數(shù)原型如下:intcJSON_GetArraySize(cJSON*array);cJSON*cJSON_GetArrayItem(cJSON*array,intitem);由于前面已經(jīng)實(shí)現(xiàn)了結(jié)構(gòu)體的解析,這里我們只需要關(guān)注下數(shù)組的相關(guān)調(diào)用即可。(1)調(diào)用cJSON_Parse()函數(shù),解析JSON數(shù)據(jù)包。(2)調(diào)用一次cJSON_GetObjectItem()函數(shù),獲取到數(shù)組people。(3)對我們剛?cè)〕鰜淼臄?shù)組people,調(diào)用cJSON_GetArraySize()函數(shù),來獲取數(shù)組中對象的個數(shù)。然后,多次調(diào)用cJSON_GetArrayItem()函數(shù),逐個讀取數(shù)組中對象的內(nèi)容。(4)通過cJSON_Delete(),釋放cJSON_Parse()分配出來的內(nèi)存空間。這樣,我們就使用cJSON接口完成了結(jié)構(gòu)體數(shù)組的解析工作。詳細(xì)代碼見后文附帶例程。說明:下面是例程,實(shí)現(xiàn)了結(jié)構(gòu)體數(shù)組的解析,只是一個學(xué)習(xí)之作,對于初學(xué)JSON使用cJSON接口的同學(xué),可以有些借鑒參考的作用。運(yùn)行環(huán)境為vs2019和stm32,兩個平臺只需修改頭文件和內(nèi)存管理函數(shù)即可。#include"stm32f10x.h"#include<stdio.h>#include<string.h>#include<stdlib.h>#include"cJSON.h"typedefstruct{intid;charfirstName[32];charlastName[32];charemail[64];intage;floatheight;}people;voiddofile(char*filename);/*Readafile,parse,renderback,etc.*/voidmain(){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級分組2delay_init();//延時函數(shù)初始化uart_init(115200);//串口初始化為9600while(1){if(USART2_RX_STA&0X8000){USART2_RX_STA=0;cJSON_to_struct_array((char*)USART2_RX_BUF,worker);t=60;while(t--)//延時,同時掃描按鍵{delay_ms(10);key=KEY_Scan(0);}LED0=!LED0;}}}//parseakey-valuepairintcJSON_to_str(char*json_string,char*str_val){cJSON*root=cJSON_Parse(json_string);if(!root){printf("Errorbefore:[%s]\n",cJSON_GetErrorPtr());return-1;}else{cJSON*item=cJSON_GetObjectItem(root,"firstName");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,keyis%s,valueis%s\n",item->type,item->string,item->valuestring);mymemcpy(str_val,item->valuestring,strlen(item->valuestring));}cJSON_Delete(root);}return0;}//parseaobjecttostructintcJSON_to_struct(char*json_string,people*person){cJSON*item;cJSON*root=cJSON_Parse(json_string);if(!root){printf("Errorbefore:[%s]\n",cJSON_GetErrorPtr());return-1;}else{cJSON*object=cJSON_GetObjectItem(root,"person");if(object==NULL){printf("Errorbefore:[%s]\n",cJSON_GetErrorPtr());cJSON_Delete(root);return-1;}printf("cJSON_GetObjectItem:type=%d,keyis%s,valueis%s\n",object->type,object->string,object->valuestring);if(object!=NULL){item=cJSON_GetObjectItem(object,"firstName");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s,valuestring=%s\n",item->type,item->string,item->valuestring);mymemcpy(person->firstName,item->valuestring,strlen(item->valuestring));}item=cJSON_GetObjectItem(object,"lastName");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s,valuestring=%s\n",item->type,item->string,item->valuestring);mymemcpy(person->lastName,item->valuestring,strlen(item->valuestring));}item=cJSON_GetObjectItem(object,"email");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s,valuestring=%s\n",item->type,item->string,item->valuestring);mymemcpy(person->email,item->valuestring,strlen(item->valuestring));}item=cJSON_GetObjectItem(object,"age");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s,valueint=%d\n",item->type,item->string,item->valueint);person->age=item->valueint;}else{printf("cJSON_GetObjectItem:getagefailed\n");}item=cJSON_GetObjectItem(object,"height");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s,valuedouble=%f\n",item->type,item->string,item->valuedouble);person->height=item->valuedouble;}}cJSON_Delete(root);}return0;}//parseastructarrayintcJSON_to_struct_array(char*text,peopleworker[]){cJSON*json,*arrayItem,*item,*object;inti;json=cJSON_Parse(text);if(!json){printf("Errorbefore:[%s]\n",cJSON_GetErrorPtr());}else{arrayItem=cJSON_GetObjectItem(json,"people");if(arrayItem!=NULL){intsize=cJSON_GetArraySize(arrayItem);printf("cJSON_GetArraySize:size=%d\n",size);for(i=0;i<size;i++){printf("i=%d\n",i);object=cJSON_GetArrayItem(arrayItem,i);item=cJSON_GetObjectItem(object,"firstName");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s\n",item->type,item->string);mymemcpy(worker[i].firstName,item->valuestring,strlen(item->valuestring));}item=cJSON_GetObjectItem(object,"lastName");if(item!=NULL){printf("cJSON_GetObjectItem:type=%d,stringis%s,valuestring=%s\n",item->type,item->string,item->valuestring);mymemcpy(worker[i].lastName,item->valuestring,strlen(item->valuestring));}item=cJSON_GetObjectItem(object,"email");if(item!=NULL){printf("cJSON_Get
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2031年中國調(diào)速電錘行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國電子選緯器行業(yè)投資前景及策略咨詢研究報告
- 2025年橡膠防震耐膠墊圈項(xiàng)目可行性研究報告
- 惠州2024年廣東惠州市中小企業(yè)服務(wù)中心招聘專業(yè)技術(shù)人員筆試歷年參考題庫附帶答案詳解
- 2025至2031年中國大提花襯衫面料行業(yè)投資前景及策略咨詢研究報告
- 2025年園林線項(xiàng)目可行性研究報告
- 2025年升降平臺項(xiàng)目可行性研究報告
- 2025年位扭腰器項(xiàng)目可行性研究報告
- 2025年4通道粗波分復(fù)用器項(xiàng)目可行性研究報告
- 廣州廣東廣州市白云區(qū)鶴龍街道市政服務(wù)所招聘環(huán)衛(wèi)工作人員筆試歷年參考題庫附帶答案詳解
- 2024版消防設(shè)計質(zhì)量問題案例分析手冊建筑機(jī)電專業(yè)
- 《義務(wù)教育道德與法治課程標(biāo)準(zhǔn)》解讀
- 2024年臨滄永德縣人民法院聘用制書記員招聘考試真題
- 中醫(yī)院發(fā)展中醫(yī)重點(diǎn)???、學(xué)科加強(qiáng)中醫(yī)藥人才培養(yǎng)的具體措施
- 2025年中國私域電商行業(yè)市場運(yùn)行態(tài)勢、市場規(guī)模及發(fā)展趨勢研究報告
- 財務(wù)核算管理制度
- 2025年浙江省重點(diǎn)高中提前自主招生數(shù)學(xué)模擬試卷(含答案)
- 弱電智能化勞務(wù)分包合同
- 藥品經(jīng)營企業(yè)(批發(fā)和零售)面臨的風(fēng)險點(diǎn)和應(yīng)對措施
- 主要施工機(jī)械設(shè)備、勞動力、設(shè)備材料投入計劃及其保證措施
- 甲狀腺乳腺外科ERAS實(shí)施流程(模板)
評論
0/150
提交評論