荐在stm32上使用cJSON解析JSON字符串.docx
- 文档编号:30608686
- 上传时间:2023-08-18
- 格式:DOCX
- 页数:14
- 大小:17.57KB
荐在stm32上使用cJSON解析JSON字符串.docx
《荐在stm32上使用cJSON解析JSON字符串.docx》由会员分享,可在线阅读,更多相关《荐在stm32上使用cJSON解析JSON字符串.docx(14页珍藏版)》请在冰豆网上搜索。
荐在stm32上使用cJSON解析JSON字符串
在stm32上使用cJSON解析JSON字符串
一、为何选择cJSON
我们在使用JSON格式时,如果只是处理简单的协议,可以依据JSON格式,通过对字符串的操作来进行解析与创建。
然而随着协议逐渐复杂起来,经常会遇到一些未考虑周全的地方,需要进一步的完善解析方法,此时,使用比较完善的JSON解析库的需求就提出来了。
二、cJSON的核心结构体
cJSON的核心结构体就是一个cJSON,理解了这个结构体,基本上对cJSON的使用就有了个基本概念了。
该结构体具体定义如下:
typedefstructcJSON{
structcJSON*next,*prev;/*遍历数组或对象链的前向或后向链表指针*/
structcJSON*child;/*数组或对象的孩子节点*/
inttype;/*key的类型*/
char*valuestring;/*字符串值*/
intvalueint;/*整数值*/
doublevaluedouble;/*浮点数值*/
char*string;/*key的名字*/
}cJSON;
说明:
1、cJSON是使用链表来存储数据的,其访问方式很像一颗树。
每一个节点可以有兄弟节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。
只有节点是对象或数组时才可以有孩子节点。
2、type是键(key)的类型,一共有7种取值,分别是:
False,Ture,NULL,Number,String,Array,Object。
若是Number类型,则valueint或valuedouble中存储着值。
若期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。
若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。
3、string中存放的是这个节点的名字,可理解为key的名称。
三、解析JSON格式;
3,解析一个键值对;
首先是一个简单的键值对字符串,要解析的目标如下:
{"firstName":
"Brett"}
要进行解析,也就是要分别获取到键与值的内容。
我们很容易就能看出键为firstName,值为Brett,可是,使用cJSON怎么解析呢?
对于这个简单的例子,只需要调用cJSON的三个接口函数就可以实现解析了,这三个函数的原型如下:
cJSON*cJSON_Parse(constchar*value);
cJSON*cJSON_GetObjectItem(cJSON*object,constchar*string);
voidcJSON_Delete(cJSON*c);
下面按解析过程来描述一次:
(1)首先调用cJSON_Parse()函数,解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包。
使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放。
cJSON*root=cJSON_Parse(json_string);
(2)调用cJSON_GetObjectItem()函数,可从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。
cJSON*item=cJSON_GetObjectItem(root,"firstName");
(3)如果需要使用cJSON结构体中的内容,可通过cJSON结构体中的valueint和valuestring取出有价值的内容(即键的值)
本例子中,我们直接访问item->valuestring就获取到"Brett"的内容了。
(4)通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。
cJSON_Delete(root);
这样就完成了一次cJSON接口调用,实现了解析工作。
使用起来其实也很简单的啊,呵呵。
4,解析一个结构体;
接下来,我们来个复杂一点的,解析一个结构体,要解析的目标如下:
{
"person":
{
"firstName":
"z",
"lastName":
"jadena",
"email":
"jadena@",
"age":
8,
"height":
1.17
}
}
看起来比一个键值对复杂多了,我们又需要学习新的接口函数了吗?
答案是不需要!
还是那三个函数就可以了。
当然,解析的步骤要复杂一些了,下面我按解析过程来描述一次:
(1)根据JSON串中的对象,我们定义一个相应的结构体如下:
typedefstruct
{
charfirstName[32];
charlastName[32];
charemail[64];
intage;
floatheight;
}PERSON;
具体的对应关系,一目了然,我就不罗嗦了。
让我们直奔主题,解析!
(2)还是调用cJSON_Parse()函数,解析JSON数据包。
cJSON*root=cJSON_Parse(json_string);
(3)调用一次cJSON_GetObjectItem()函数,获取到对象person。
cJSON*object=cJSON_GetObjectItem(root,"person");
(4)对我们刚取出来的对象person,多次调用cJSON_GetObjectItem()函数,来获取对象的成员。
此时要注意,不同的成员,访问的方法不一样:
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;
这样,就获取到了对象的全部内容了。
(5)通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。
cJSON_Delete(root);
至此,我们就使用cJSON接口完成了基于结构体的解析工作。
5,解析结构体数组的JSON串;
最后,我们来个更复杂一些的,来解析一个数组,并且数组的成员是结构体!
要解析的JSON串如下:
{
"people":
[
{"firstName":
"z","lastName":
"Jason","email":
"bbbb@","height":
1.67},
{"lastName":
"jadena","email":
"jadena@","age":
8,"height":
1.17},
{"email":
"cccc@","firstName":
"z","lastName":
"Juliet","age":
36,"height":
1.55}
]
}
此时,我们真的又需要学习新的接口了,一个是获取数组长度,一个是取数组成员,函数原型如下:
intcJSON_GetArraySize(cJSON*array);
cJSON*cJSON_GetArrayItem(cJSON*array,intitem);
由于前面已经实现了结构体的解析,这里我们只需要关注下数组的相关调用即可。
(1)调用cJSON_Parse()函数,解析JSON数据包。
(2)调用一次cJSON_GetObjectItem()函数,获取到数组people。
(3)对我们刚取出来的数组people,调用cJSON_GetArraySize()函数,来获取数组中对象的个数。
然后,多次调用cJSON_GetArrayItem()函数,逐个读取数组中对象的内容。
(4)通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。
这样,我们就使用cJSON接口完成了结构体数组的解析工作。
详细代码见后文附带例程。
说明:
下面是例程,实现了结构体数组的解析,只是一个学习之作,对于初学JSON使用cJSON接口的同学,可以有些借鉴参考的作用。
运行环境为vs2019和stm32,两个平台只需修改头文件和内存管理函数即可。
#include"stm32f10x.h"
#include
#include
#include
#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);//设置中断优先级分组2
delay_init();//延时函数初始化
uart_init(115200);//串口初始化为9600
while
(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-valuepair
intcJSON_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;
}
//parseaobjecttostruct
intcJSON_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;
}
//parseastructarray
intcJSON_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 { 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_GetObjectItem: type=%d,stringis%s,valuestring=%s\n",item->type,item->string,item->valuestring); mymemcpy(worker[i].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); worker[i].age=item->valueint; } else { printf("cJSON_GetObjectItem: getagefailed\n"); } item=cJSON_GetObjectItem(object,"height"); if(item! =NULL) { printf("cJSON_GetObjectItem: type=%d,stringis%s,value=%f\n",item->type,item->string,item->valuedouble); worker[i].height=item->valuedouble; } } } for(i=0;i<3;i++) { printf("i=%d,firstName=%s,lastName=%s,email=%s,age=%d,height=%f\n", i, worker[i].firstName, worker[i].lastName, worker[i].email, worker[i].age, worker[i].height); } cJSON_Delete(json); } return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- stm32 使用 cJSON 解析 JSON 字符串
![提示](https://static.bdocx.com/images/bang_tan.gif)