Esp8266 进阶之路28 【高级篇】教你轻松自如使用cJson在乐鑫 esp8266 如何解析一段json数据以及如何生成一段json数据。(附带demo)

版权声明:本文为博主半颗心脏一心一血敲出来的原创作品,未经博主允许不得转载,多谢支持。 https://blog.csdn.net/xh870189248/article/details/82459279


一、前言;


    大半个月没有更新博客了,最近在搞阿里的alios-things,终于有空更新了下博客,前几天在咱们的群看到有人问怎么剖析一段json数据,其实在8266这个非常容易实现。那么本文将直接带你怎么实现解析一段json以及如何生成一段json;

二、什么是JSON


  • 这个问题其实百度一大堆,我这里浅显说下,它就是一种数据格式,注意:是数据格式,不是协议!最初来源于JavaScript,之后被广泛使用在各个语言中,因为它轻量小,适合数据交互;

  • 其实,在乐鑫也有提供这么一个json使用库,但是我一般不会去独立去研究它,因为习惯了一个非常强大著名的嵌入式专用的cJSON库。。那么本博文也是基于cJSON库来解析一段json数据以及如何生成一段json数据,以及注意在使用过程中的一些问题!!!


三、如何解析一段JSON


  • 解析下面一段数据:
    • 包括字符串,整型,数组型;
{
    "mac": "84:f3:eb:b3:a7:05",
    "number": 2,
    "value": {
        "name": "xuhongv",
        "age": 18,
        "blog": "https://blog.csdn.net/xh870189248"
    },
    "hexArry": [51, 15, 63, 22, 96]
}

思路:

1、先确定是否正确的json格式,通过网上的在线监测是否json数据的网址:
这里写图片描述

2、我们先判断整体是否一个json格式数据:


    // jsonRoot 是您要剖析的数据
    //首先整体判断是否为一个json格式的数据
    cJSON *pJsonRoot = cJSON_Parse(jsonRoot);
    //如果是否json格式数据
    if (pJsonRoot !=NULL) {
    }

3、我们一层一层来剖析json格式数据:

  • 3.1 先从mac字段开始:
    //解析mac字段字符串内容
        cJSON *pMacAdress = cJSON_GetObjectItem(pJsonRoot, "mac");
        //判断mac字段是否json格式
        if (pMacAdress) {
            //判断mac字段是否string类型
            if (cJSON_IsString(pMacAdress))
                os_printf("get MacAdress:%s \n", pMacAdress->valuestring);
        } else
            os_printf("get MacAdress failed \n");
  • 3.2 再到我们的number
        //解析number字段int内容
        cJSON *pNumber = cJSON_GetObjectItem(pJsonRoot, "number");
        //判断number字段是否存在
        if (pNumber){
             //判断mac字段是否数字整型类型
            if (cJSON_IsNumber(pNumber))
            os_printf("get Number:%d \n", pNumber->valueint);
        }
        else
            os_printf("get Number failed \n");
  • 3.3 再仔细看看我们的 value,其实它里面包含的内容就是json格式,因此我们把它当做是一个json对象:
        //解析value字段内容,判断是否为json
        cJSON *pValue = cJSON_GetObjectItem(pJsonRoot, "value");
        if (pValue) {
            //进一步剖析里面的name字段:注意这个根节点是 pValue
            cJSON *pName = cJSON_GetObjectItem(pValue, "name");
            if (pName)
                if (cJSON_IsString(pName))
                    os_printf("get value->Name : %s \n", pName->valuestring);

            //进一步剖析里面的age字段:注意这个根节点是 pValue
            cJSON *pAge = cJSON_GetObjectItem(pValue, "age");
            if (pAge)
                if (cJSON_IsNumber(pAge))
                    os_printf("get value->Age : %d \n", pAge->valueint);


            //进一步剖析里面的blog字段:注意这个根节点是 pValue
            cJSON *pBlog= cJSON_GetObjectItem(pValue, "blog");
            if (pBlog)
                if (cJSON_IsString(pBlog))
                os_printf("get value->pBlog  : %s \n", pBlog->valuestring);
        }

  • 3.4 下面这段就有点意思了,是解析数组,先获取里面的长度,然后逐个打印一下:
    //剖析
    cJSON *pArry = cJSON_GetObjectItem(pJsonRoot, "hexArry");
    if (pArry) {
    //获取数组长度
    int arryLength = cJSON_GetArraySize(pArry);
    os_printf("get arryLength : %d \n", arryLength);
    //逐个打印
    int i ;
    for (i = 0; i < arryLength; i++)
    os_printf("cJSON_GetArrayItem(pArry, %d)= %d\n",i,cJSON_GetArrayItem(pArry, i)->valueint);  
    }

  • 看看打印:
    这里写图片描述

四、如何生成一段JSON


  • 生成json格式的方法很多种,我觉得最大效率的就是用sprintf()函数,这个是傻瓜式,直接套模板就行了。既然说到了cJson那么我们肯定会教大家怎么使用生成的,好吧!

  • 下面生成这个json格式信息,其中mac字段的地址是根据自己的设备动态生成的,是不是有点意思?

{
    "mac":  "65:c6:3a:b2:33:c8",
    "number":   2,
    "value":    {
        "mac":  "xuhongv",
        "age":  18,
        "mac":  "https://blog.csdn.net/xh870189248"
    },
    "hex":  [51, 15, 63, 22, 96]
}

  • 代码比较少,我直接上全部:
    //取一下本地的station的mac地址,保存在全局变量tempMessage
    initGetMacAdress();

    cJSON *pRoot = cJSON_CreateObject();
    cJSON *pValue = cJSON_CreateObject();

    //新增一个字段mac到根点,数值是tempMessage
    cJSON_AddStringToObject(pRoot,"mac",tempMessage);
    //新增一个字段number到根点,数值是2
    cJSON_AddNumberToObject(pRoot,"number",2);

    cJSON_AddStringToObject(pValue,"mac","xuhongv");
    cJSON_AddNumberToObject(pValue,"age",18);
    cJSON_AddStringToObject(pValue,"mac","https://blog.csdn.net/xh870189248");

    cJSON_AddItemToObject(pRoot, "value",pValue);

    //数组初始化
    int hex[5]={51,15,63,22,96};
    cJSON *pHex = cJSON_CreateIntArray(hex,5);
    cJSON_AddItemToObject(pRoot,"hex",pHex);

    char *s = cJSON_Print(pRoot);
    os_printf("\r\n creatJson : %s\r\n", s);

    //释放内存
    cJSON_free((void *) s);
    cJSON_Delete(pRoot);

五、cJSON库常见的函数说明;


这里我就介绍下我们常见常用的函数说明,绝对原创:

  • 1、 cJSON_Parse( const char *value );

开始识别一个字符串是否为json格式,返回数值就是一个cJSON,如果返回的cJSONNULL则表示不是json格式,否则就是json格式。

  • 2、cJSON_GetObjectItem( const cJSON * const object, const char * const string );

从一个json格式数据剖析一个指定的字段的数据,返回数值就是一个cJSON,如果返回的cJSONNULL则表示获取失败,否则获取成功!

  • 3、cJSON_IsString(const cJSON * const item);

从一个json格式数据判断是否为字符串类型,返回数值就是一个布尔值,如果返回false则表示这个字段是字符串类型,否则不是!以此类推,其他的cJSON_IsBool()cJSON_IsNumber()都是一样的意思!

  • 3、cJSON_GetArraySize(const cJSON *array);

从一个json格式的数组数据获取该数组的长度。

  • 4、cJSON_GetArrayItem(const cJSON *array, int index);

从一个json格式的数组获取该数组的指定索引的元素,index是下标。

  • 5、 cJSON_Print(const cJSON *item);

返回一个json格式的数据,返回时char*类型,注意使用后要释放内存。调用cJSON_free()即可!!

  • 6、 cJSON_Delete(cJSON *c);

释放一个json格式的数据所占的内存,注意一般使用这个数据之后,释放根节点即可!!

  • 7、 cJSON_AddStringToObject(object,name,s) ;

新增一个字符串类型字段到json格式的数据!name是字段,s是数值。

  • 8、 cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);

新增一个新的子节点cJSON到根节点!string是字段名字!


六、cJSON—–小徐告诫编程注意的问题;


1、注意每次使用(包括剖析和生成)之后,都要记得释放内存,就是调用cJSON_Delete()方法,否则一直在占据内存,像8266这样的本身内存就少,运行久了就会死机的 !

2、在剖析数据时候,一定要遵循规范,一定要判断是否json数据,而且是否想要的类型,比如字符串,整型,这些都是要认真核对。否则会造成esp8266重启。

3、在处理数组时候,一定要注意不要数组越界问题!最后,祝大家养成好的编程习惯,受益终生。

七、其他;


猜你喜欢

转载自blog.csdn.net/xh870189248/article/details/82459279