1198|2

5064

帖子

4

TA的资源

版主

 

esp32组件库cJSON 轻量级C语言JSON解析器(一) [复制链接]

本帖最后由 damiaa 于 2023-4-23 16:34 编辑

                                            esp32组件库cJSON  轻量级C语言JSON解析器 (一)

说起esp32,搞嵌入式的基本上都知道,很多人还用过。esp32现在是越来越受欢迎。不断扩展的芯片种类,wifi 蓝牙 无线的各种支持。特别是还有组件库可以供大家使用。蛮开心的。

 

下面介绍一下esp32组件库中的cJSON。

JSON现在是越来越多的人使用了:JSON —— 轻量级的数据格式

它采用完全独立于编程语言的文本格式来存储和表示数据,语法简洁、层次结构清晰,易于人阅读和编写,同时也易于机器解析和生成,有效的提升了网络传输效率。


JSON对象是一个无序的"名称/值"键值对的集合:

"{“开始,以”}"结束,允许嵌套使用;
1,名称和值成对出现,名称和值之间使用":"分隔;
2,键值对之间用","分隔
3,在这些字符前后允许存在无意义的空白符;
4,对于键值,可以有如下值:

     数组:用"[“和”]"表示
     数字:直接表示,可以是整数,也可以是浮点数
    字符串:使用引号"表示
    字面值:false、null、true中的一个(必须小写)

如:

{
    "name": "switch",
    "address": 1,
    "pararmeter":
    {
        "How many roads": 2,
        "OnOff": ["first","on", "second","off"]

    }

}

 

cJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。

http://github.com/DaveGamble/cJSON有它的源码

esp32移植进了它的组件库。

cJSON其实只有两个文件cJSON.h和 cJSON.c

 

cJSON使用cJSON结构体来表示一个JSON数据键值对 ,定义在cJSON.h中:


typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

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

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

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

 

cJSON设计

它不是一整段JSON数据抽象出来,而是其中的一条JSON数据抽象出来,也就是一个键值对,用上面的结构体 strcut cJSON 表示,用来存放值的成员列表如下:

String:         键值对的名称;
type:            键值对中值的类型;
valuestring:  键值类型(type)是字符串,则将该指针指向键值;
valueint:       键值类型(type)是整数,则将该指针指向键值;
valuedouble:键值类型(type)是浮点数,则将该指针指向键值;

next指针:指向下一个键值对
prev指针:指向上一个键值对

完整的JSON数据中由很多键值对组成,涉及到键值对的查找、删除、添加,使用链表来存储整段JSON数据就很方便,如上面的代码,所以用到了next指针和prev指针。

child指针
JSON数据支持嵌套,一个键值对的值会是一个新的JSON数据对象(一条新的链表),也可能是一个数组,在cJSON中,数组也表示为一个数组对象,用链表存储,所以:

在键值对结构体中,当该键值对的值是一个嵌套的JSON数据或者一个数组时,由child指针指向该条新链表。

 

这样 JOSN数据就可以很好的组合起来,也方便查找、删除、添加等各种操作。

 

封装JSON数据,就是创建链表和向链表中添加节点。

链表:包含

   头指针:链表头结点的指针;

   头结点:不存放有效数据,方便链表操作;

   首节点:存放有效数据的第一个节点;

   尾节点:存放有效数据的最后节点;

一些用到得api(或更多api参见cJSON.h和cJSON.c):

CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);//创建头指针和创建头节点:

//多条向链表中添加节点的api(根据数据类型区分):

CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);

CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);

CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);

CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);

CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);

CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);

CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);

CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);

CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);

CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);//cJSON打印API,可以将整条链表中的JSON信息输出到一个字符串中:

 

cJSON打印数据实例

//{
//    "name": "switch",
//    "address": 1,
//    "pararmeter":
//    {
//        "How many roads": 2,
//        "OnOff": ["first","on", "second","off"]
//    }
//}
#include <stdio.h>
#include "cJSON.h"
int main(void)
{
    cJSON *cjson_root = cJSON_CreateObject();/* 创建一个JSON数据对象(链表头结点) */
    cJSON_AddStringToObject(cjson_root, "name", "switch");/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
    cJSON_AddNumberToObject(cjson_root, "address", 1);/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
    cJSON *cjson_pararmeter = cJSON_CreateObject();/* 创建一个嵌套的JSON数据 */
    cJSON_AddNumberToObject(cjson_pararmeter, "How many roads", 2);/* 添加一条数字类型的JSON数据(到子节点) */
    cJSON *cjson_OnOff = cJSON_CreateArray();/* 创建一个嵌套的数组 JSON数据 */
    cJSON_AddItemToArray(cjson_OnOff, cJSON_CreateString( "first" ));
    cJSON_AddItemToArray(cjson_OnOff, cJSON_CreateString( "on" ));
    cJSON_AddItemToArray(cjson_OnOff, cJSON_CreateString( "second" ));
    cJSON_AddItemToArray(cjson_OnOff, cJSON_CreateString( "off" ));
    cJSON_AddNumberToObject(cjson_pararmeter, "OnOff", cjson_OnOff);/* 添加一条数字类型的JSON数据(到子节点) */
    cJSON_AddItemToObject(cjson_root, "pararmeter", cjson_pararmeter);/* 添加一个嵌套的JSON数据(添加一个链表节点) */
    /* 打印JSON对象(整条链表)的所有数据 */
    char *p = cJSON_Print(cjson_root);
    printf("%s\n", p);
    cJSON_Delete(cjson_root);
    while(1){};
}

(后续)

 

 

此帖出自单片机论坛

最新回复

c/c++处理json还是比较繁琐。   详情 回复 发表于 2023-4-25 13:56
 

回复

6577

帖子

2

TA的资源

五彩晶圆(中级)

 

c/c++处理json还是比较繁琐。

此帖出自单片机论坛

点评

是啊 只是有了这个组件方便使用。 如果直接调用字符串输出也是一样可以的。 解析的话直接查找键值对的名称部分就可以找到后面的键值。  详情 回复 发表于 2023-4-25 15:49
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 

回复

5064

帖子

4

TA的资源

版主

 
freebsder 发表于 2023-4-25 13:56 c/c++处理json还是比较繁琐。

是啊 只是有了这个组件方便使用。

如果直接调用字符串输出也是一样可以的。

解析的话直接查找键值对的名称部分就可以找到后面的键值。

此帖出自单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
幽默短信2

开学第一天,校务主任向学生作报告,他强调了几条校规:“女生宿舍禁止男生入内,同样,男生宿舍禁止女生入内。有谁违反,第一次 ...

转帖:办公室里的22条潜规则

第一条 必须有一个圈子。无论如何做都是画地为牢:不加入一个圈子,就成为所有人的敌人;加入一个圈子,就成为另一个圈子的敌人 ...

晒一个完整的LM3S811完成的小综合项目,语句详解。

一个LM3S811的EV板项目,涉及PWM、计数、字符液晶,超声测距,计时采用的是SYSTICK(比TIMER省事),附带时钟显示(简易的,不是 ...

【C2000 LaunchPad】UART作为调试监视

UART作为调试监视C2000 LaunchPad带的V2版仿真器,不仅有仿真调试功能,也有串口----UART功能, 在调试时,使用它的UART来监视C ...

MSP430单片机的开关电源

作者:Freedomz 1 引 言 MSP430系列单片机是美国TI公司生产的新一代16位单片机,是一种超低功耗的混合信号处理器(MixedSigna ...

TinyGo,单片机的GO语言

TinyGo是一个用于微控制器的Go编译器,使用WebAssembly(WASM)和命令行工具。它重用了Go语言工具和LLVM一起使用的库,编译用Go ...

求 C8051F58x/F59x IDE ?

求 C8051F58x/F59x IDE 。 非常感谢!

可折叠电子设备到底有没有意义?

让设备折叠或弯曲,使智能手机变身成小型平板电脑或计算机。但这种技术若能成功,取决于三个主要因素:成本、简便性和实用性。 ...

ST发布世界上首款LoRa Soc单片机STM32WL

全球首款LoRa SOC芯片——STM32WL全新发布 https://www.stmcu.com.cn/video/1519 远距离无线STM32WL ...

开发板STEVAL-IDB007V1使用USB micro B串口时串口识别不了

求助各位大侠,开发板STEVAL-IDB007V1使用USB micro 连接PC- USB,设备管理器里识别不了串口

关闭
站长推荐上一条 1/8 下一条
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2023 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表