智能硬件數(shù)據(jù)傳輸之CJSON轉(zhuǎn)化

來點(diǎn)兒干貨蒋荚,今天白天主要時(shí)間都在車上,于是繼續(xù)完善這篇文章贷祈。

原本以為在寫上一條引用的時(shí)候可以把這篇完成狈醉,結(jié)果中途又遇到了一些問題,自己對(duì)JSON的語法規(guī)則并沒有很理解牲芋,這是停留在應(yīng)用層面撩笆。于是捺球,在業(yè)余時(shí)間,擠了擠時(shí)間夕冲,看了一些JSON的語法知識(shí)氮兵。

前言

  • 寫技術(shù)文章確實(shí)是一件很難的事情,寫出來容易歹鱼,要自己理解泣栈,同時(shí)還要讓讀者看懂,真的是一件很不容易的事情弥姻。與君共勉南片。

1 概述

  • 物聯(lián)網(wǎng)產(chǎn)品免不了和服務(wù)器做交互,目前使用的比較多的是以太網(wǎng)接網(wǎng)線或者WiFi設(shè)備或者GPRS庭敦。
  • 無論是用的透?jìng)魈劢€是非透?jìng)鞯姆绞剑夹枰獙⒂布a(chǎn)生的原始數(shù)據(jù)轉(zhuǎn)換為服務(wù)器端的物聯(lián)網(wǎng)數(shù)據(jù)秧廉,硬件處理服務(wù)端的物聯(lián)網(wǎng)數(shù)據(jù)時(shí)颠悬,也需要轉(zhuǎn)化為十六進(jìn)制的數(shù)據(jù),方便處理定血。
  • 這里涉及到了兩個(gè)問題赔癌,JSON數(shù)據(jù)包的解析和組裝。
  • 硬件設(shè)備使用的基本都是C語言澜沟,同時(shí)考慮成本等因素灾票,單片機(jī)的RAM也是KB級(jí)的比較多。
  • 此文章重點(diǎn)講解一下一個(gè)非常好用的CJSON庫茫虽,在MDK中編譯的代碼量只有十幾KB刊苍,占用的RAM只有幾KB
  • 該JSON庫具有占用空間小(ROM占用10K以內(nèi)濒析,易移植(只有一個(gè)c文件和一個(gè)h文件)正什,使用簡(jiǎn)單(只需要掌握幾個(gè)常用的函數(shù),和一個(gè)CJSON結(jié)構(gòu)體就可以輕松地使用)的特點(diǎn)号杏。包含到項(xiàng)目源碼中非常方便婴氮,而且其實(shí)現(xiàn)效率也是非常高的。

2 JSON

  • 先貼一段JSON數(shù)據(jù)盾致,閱讀下文時(shí)可以參考一下對(duì)應(yīng)的數(shù)據(jù)格式
{
    "msg": [
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 65,
            "isLocked": true,
            "locksNo": "1001001105",
            "pwd": {
                "1": "654321",
                "2": "147258"
            }
        },
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 66,
            "isLocked": false,
            "locksNo": "1001001106",
            "pwd": {
                "1": "123456",
                "2": “147258"
            }
        }
    ],
    "code": 0
}
  • 下文對(duì)JSON的介紹來自筆者看了大量教程以后的總結(jié)主经。

2.1JSON 語法規(guī)則

JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。

  1. 結(jié)構(gòu)特點(diǎn)
  • 數(shù)據(jù)在名稱/值對(duì)中
  • 數(shù)據(jù)由逗號(hào)分隔
  • 大括號(hào)保存對(duì)象
  • 中括號(hào)保存數(shù)組
  • 鍵庭惜、值可層層嵌套
  1. 說明一下:鍵罩驻、值可層層嵌套
  • 理解該特點(diǎn)是運(yùn)用JSON的關(guān)鍵。
  • JSON的值可以為以下類型:
    數(shù)字(整數(shù)或浮點(diǎn)數(shù))
    字符串(在雙引號(hào)中)
    邏輯值(true 或 false)
    數(shù)組(在方括號(hào)中)
    對(duì)象(在花括號(hào)中)
    null(在不同的語言表示的意義不一樣护赊,開發(fā)者只需要知道在自己的語言里的意義就可以了)
  • JSON的值為數(shù)組時(shí)惠遏,數(shù)組可以是數(shù)字?jǐn)?shù)組砾跃,字符串?dāng)?shù)組,對(duì)象數(shù)組等节吮,所以該值里面又會(huì)包含很多鍵值對(duì)
  • 解析JSON的核心也是一層一層地往外撥蜓席,反復(fù)地調(diào)用一個(gè)或者兩個(gè)方法(下文會(huì)詳細(xì)介紹)

2.2 JSON值

2.2.3 JSON數(shù)字

"locksId": 65,

2.2.4 JSON字符串

"ctime": "20170916091927",

2.2.5 JSON邏輯值

"isLocked": false,

2.2.6 JSON數(shù)組

  • "msg"對(duì)應(yīng)的值為一個(gè)數(shù)組,數(shù)組里面有兩個(gè)對(duì)象(花括號(hào))元素课锌,
    "msg": [
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 65,
            "isLocked": true,
            "locksNo": "1001001105",
            "pwd": {
                "1": "654321",
                "2": "147258"
            }
        },
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 66,
            "isLocked": false,
            "locksNo": "1001001106",
            "pwd": {
                "1": "123456",
                "2": “147258"
            }
        }
    ],

2.2.7 JSON對(duì)象

  • 一個(gè)對(duì)象里面一般會(huì)包含多種類型的值,里面的“pwd”對(duì)應(yīng)的值也是一個(gè)對(duì)象
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 66,
            "isLocked": false,
            "locksNo": "1001001106",
            "pwd": {
                "1": "123456",
                "2": “147258"
            }
        }

看到祈秕,應(yīng)該可以深入感受一下上文提到的"鍵渺贤、值可層層嵌套"

2.2.8 介紹一下JSON數(shù)據(jù)格式

  • Object,Item,Array

筆者需要補(bǔ)充一下json的數(shù)據(jù)格式,學(xué)習(xí)中请毛。志鞍。。方仿。固棚。。

  • 該小節(jié)作為一章的內(nèi)容放在了第2章中仙蚜。

3 介紹CJOSN的結(jié)構(gòu)

  • 核心結(jié)構(gòu)體
/* The cJSON structure: */
typedef struct cJSON {
    struct cJSON *next,*prev;   /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *child;        /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

    int type;                   /* The type of the item, as above. */

    char *valuestring;          /* The item's string, if type==cJSON_String */
    int valueint;               /* The item's number, if type==cJSON_Number */
    double valuedouble;         /* The item's number, if type==cJSON_Number */

    char *string;               /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

這個(gè)結(jié)構(gòu)體包含了所有的返回?cái)?shù)據(jù)類型此洲。

4 介紹CJSON的解析

4.1 解析使用的核心函數(shù)如下

 cJSON *cJSON_Parse(const char *value);
 void   cJSON_Delete(cJSON *c);
 int      cJSON_GetArraySize(cJSON *array);
 cJSON *cJSON_GetArrayItem(cJSON *array,int item);
 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
  1. 一共五個(gè)函數(shù), 前三個(gè)函數(shù)使用的位置和方法都很固定委粉,后兩個(gè)就是在獲取數(shù)據(jù)的時(shí)候反復(fù)調(diào)用呜师,目的就是走到JSON數(shù)據(jù)的最底部--獲取健值。
  2. 總結(jié)一下就是:三個(gè)函數(shù)固定使用贾节,目的是獲取待處理的數(shù)據(jù)或者做收尾工作汁汗;兩個(gè)函數(shù)反復(fù)使用,目的是一層一層往下栗涂,獲取到基本數(shù)據(jù)知牌。
 cJSON *cJSON_Parse(const char *value);
  • 該函數(shù)是接收到j(luò)son字符串時(shí),將字符串轉(zhuǎn)為json格式的字符串斤程,一般都是在解析的第一行主要代碼的位置角寸。
 void   cJSON_Delete(cJSON *c);
  • 該函數(shù)是在解析完成以后,用于釋放內(nèi)存忿墅。
 int      cJSON_GetArraySize(cJSON *array);
  • 該函數(shù)是在有數(shù)組的時(shí)候袭厂,且不知道數(shù)組長(zhǎng)度的情況下,獲取數(shù)組的長(zhǎng)度球匕,然后再用循環(huán)挨個(gè)解析數(shù)組纹磺。如果需要解析的數(shù)據(jù)里面沒有數(shù)組的話,或者可以知道數(shù)組的具體長(zhǎng)度的話亮曹,就不需要使用該函數(shù)橄杨。
  1. 下面是兩個(gè)最重要的函數(shù)秘症,熟練掌握了這兩個(gè)函數(shù),大多數(shù)的場(chǎng)景都可以應(yīng)對(duì)了式矫。
 cJSON *cJSON_GetArrayItem(cJSON *array,int item);
  • 該函數(shù)的作用是獲取數(shù)組里面的元素乡摹,元素可以是對(duì)象,字符串采转,數(shù)值等各種類型聪廉。
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
  • 該函數(shù)的作用是獲取對(duì)象里面,鍵對(duì)應(yīng)的值故慈。

4.2 解析舉例說明

4.2.1數(shù)據(jù)分析

  • 還是用上面的的例子板熊,貼下源數(shù)據(jù)
{
    "msg": [
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 65,
            "isLocked": true,
            "locksNo": "1001001105",
            "pwd": {
                "1": "654321",
                "2": "147258"
            }
        },
        {
            "ctime": "20170916091927",
            "gateLine": "ON",
            "locksId": 66,
            "isLocked": false,
            "locksNo": "1001001106",
            "pwd": {
                "1": "123456",
                "2": “147258"
            }
        }
    ],
    "code": 0
}
  • 簡(jiǎn)單分析一下
    分析務(wù)必搞清楚幾點(diǎn):
    1.第二章里面介紹的結(jié)構(gòu)
    2.上文提到的五個(gè)方法,有不明白的可往上翻
  1. 最外圍結(jié)構(gòu)為一個(gè)對(duì)象(花括號(hào))察绷。使用cJSON_Parse就可以獲取到JSON對(duì)象內(nèi)容
  2. 對(duì)象當(dāng)中包含了兩個(gè)Item干签,分別是"msg"和"code"。
  3. "code"對(duì)應(yīng)的是一個(gè)數(shù)字拆撼,一次解析可以獲得數(shù)據(jù)容劳。使用cJSON_GetObjectItem,獲取返回的int類型數(shù)據(jù)
  4. "msg"里面包含了一個(gè)JSON數(shù)組闸度,每個(gè)數(shù)組的元素為一個(gè)對(duì)象竭贩。使用cJSON_GetObjectItem,返回值是一個(gè)array
  5. 先獲取到array的數(shù)量莺禁。使用cJSON_GetArraySize
  6. 用for循環(huán)對(duì)每個(gè)數(shù)組里面的對(duì)象元素做解析cJSON_GetArrayItem娶视,返回一個(gè)對(duì)象
  7. 反復(fù)對(duì)對(duì)象做解析,就可以獲取所有的數(shù)據(jù)睁宰。反復(fù)使用cJSON_GetObjectItem

4.2.2 貼一小段代碼示例

  • 筆者不喜歡貼代碼肪获,雖然很多讀者都喜歡直接看代碼
  • 還是那句話,看代碼引用起來快柒傻,但是后期維護(hù)更多的時(shí)間來搞清楚算法
  • 下面提到的步驟1孝赫,2,3红符,4....對(duì)應(yīng)上文簡(jiǎn)單分析的7個(gè)步驟青柄,一一對(duì)應(yīng)看即可。
步驟1
    Mother_obj=cJSON_Parse(json_string);
                                                //json_string為源數(shù)據(jù)的字符數(shù)組
                                                //Mother_obj為整個(gè)花括號(hào)對(duì)應(yīng)的對(duì)象
步驟2预侯,3
    arry_obj_item = cJSON_GetObjectItem(Mother_obj,"code");
    json_int_buf=arry_obj_item->valueint;
                                                //獲取code的值
步驟4
    array = cJSON_GetObjectItem(Mother_obj,"msg");
                                                //獲取“msg”的數(shù)組值
步驟5
lock_array_len = cJSON_GetArraySize(array);
                                                //獲取數(shù)組里面的元素個(gè)數(shù)
步驟6致开,7
        for(i=0;i<lock_array_len;i++){

            array_obj = cJSON_GetArrayItem(array,i);
                                                //獲取數(shù)組里面的元素對(duì)象
//后面就對(duì)對(duì)象做處理,反復(fù)調(diào)用cJSON_GetObjectItem即可
            if(array_obj==NULL)continue;
//獲取“time”對(duì)應(yīng)的值
            arry_obj_item = cJSON_GetObjectItem(array_obj,"ctime");
            if(arry_obj_item==NULL)continue;
            json_buf = arry_obj_item->valuestring;
//獲取“l(fā)ockId”對(duì)應(yīng)的值
            arry_obj_item = cJSON_GetObjectItem(array_obj,"locksId");
            if(arry_obj_item==NULL)continue;
            json_int_buf = arry_obj_item->valueint;
        }   

按照層層嵌套的邏輯萎馅,就可以解析出整個(gè)字符串

5 介紹CJSON的數(shù)據(jù)組合

  • 下一篇繼續(xù)介紹

CrekerLi双戳,與君共勉于技術(shù)之路上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市糜芳,隨后出現(xiàn)的幾起案子飒货,更是在濱河造成了極大的恐慌魄衅,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塘辅,死亡現(xiàn)場(chǎng)離奇詭異晃虫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扣墩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門哲银,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呻惕,你說我怎么就攤上這事荆责。” “怎么了蟆融?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)守呜。 經(jīng)常有香客問我型酥,道長(zhǎng),這世上最難降的妖魔是什么查乒? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任弥喉,我火速辦了婚禮,結(jié)果婚禮上玛迄,老公的妹妹穿的比我還像新娘由境。我一直安慰自己,他們只是感情好蓖议,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布虏杰。 她就那樣靜靜地躺著,像睡著了一般勒虾。 火紅的嫁衣襯著肌膚如雪纺阔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天修然,我揣著相機(jī)與錄音笛钝,去河邊找鬼。 笑死愕宋,一個(gè)胖子當(dāng)著我的面吹牛玻靡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播中贝,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼囤捻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了邻寿?” 一聲冷哼從身側(cè)響起最蕾,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤依溯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后瘟则,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黎炉,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年醋拧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了慷嗜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丹壕,死狀恐怖庆械,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菌赖,我是刑警寧澤缭乘,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站琉用,受9級(jí)特大地震影響堕绩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜邑时,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一奴紧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晶丘,春花似錦黍氮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滚秩,卻和暖如春件缸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叔遂。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工他炊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人已艰。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓痊末,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親哩掺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凿叠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器盒件,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,216評(píng)論 0 4
  • 女性自述: 關(guān)鍵詞:冠冕堂皇的分手冷老師炒刁,在同事聚會(huì)后男友跟我提了分手恩沽,和男友是一家公司同事,我94翔始,他92罗心,不是...
    冷愛閱讀 287評(píng)論 0 0
  • 引: 看《八卦醫(yī)學(xué)史》的時(shí)候,還不知道阿寶是誰城瞎,拿到《八卦醫(yī)學(xué)史2》的時(shí)候渤闷,已經(jīng)參加過阿寶的簽售活動(dòng),見過活的“燒...
    djfish閱讀 573評(píng)論 0 50
  • 第17幅思維導(dǎo)圖是滅蚊方法脖镀。 中心圖是蚊子飒箭。 第一主分支是生物滅蚊方法,包括植物和動(dòng)物的滅蚊方法蜒灰。 第二主分支是物...
    開心的我們閱讀 676評(píng)論 1 0