0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用cJSON库来做数据组包及数据解析分享

Dp1040 来源:嵌入式大杂烩 2023-09-25 09:10 次阅读

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。JSON在互联网相关开发中用得很多,在我们嵌入式中用得也不少。最近小编在项目中也有用到,分享分享。

简单的JSON格式数据如:

{
"name":"xxx",
"num":xxx,
"c_score":xxx
}

这里我们需要知道一个概念:键值对。比如:

"name":"xxx"

像这样子的就是一对键值对。

当我们作为发送方时,我们要把xxx这些有用的数据组合成JSON格式的数据发送给接收方;当我们作为接收方时,我们需要从这一堆JSON数据中解析出xxx这些有用的数据拿来使用。

简单的JSON数据,我们使用C语言的一些字符串操作相关的库函数也是可以做到组包和解析的,但是一些稍微复杂一点的JSON,可能就没那么好操作了。

这时候我们可以借助一个第三方库——cJSON库,可以很方便来做数据组包及解析。

下面,我们通过实例来分享使用cJSON库来做数据组包及数据解析。

一、组包与解析示例

1、确定协议数据

在实际开发中,要把JSON数据作为通信的数据,自然要先确定通信双方要交互的数据有哪些,如有需要还需编写形成协议文档。协议文档包含要传输的数据,数据类型等信息

比如:

bc2e7e74-5b3b-11ee-939d-92fbcf53809c.png

2、组JSON数据包示例

从控制台输入一些学生信息,组合成字符串格式的JSON数据包,然后再输出至控制台。

操作示例:

bc539ff6-5b3b-11ee-939d-92fbcf53809c.png

首先,我们先从仓库下载cJSON源码,文件夹内容如:

bc696296-5b3b-11ee-939d-92fbcf53809c.png

我们只需要把cJSON.c、cJSON.h两个文件复制到我们工程的根目录下就可以使用,如:

bc82b0c0-5b3b-11ee-939d-92fbcf53809c.png

从cJSON.h可以看到其给我们提供了很多接口:

bc91fff8-5b3b-11ee-939d-92fbcf53809c.png

本例中我们重点关注如下几个接口即可:

cJSON_CreateObject:创建JSON对象,{}扩起来的
cJSON_CreateString:创建字符串
cJSON_CreateNumber:创建int类型数据
cJSON_AddItemToObject:添加到JSON对象中
cJSON_Print:呈现为标准的JSON格式
cJSON_PrintUnformatted:呈现为去掉空格的JSON格式
cJSON_Delete:JSON对象删除,做一些释放内存的工作

我们创建的的组包函数如下:

staticchar*StudentsData_Packet(pStudentDef _Stu)
{
char*res_string=NULL;//返回值
cJSON*name=NULL;//名字
cJSON*num=NULL;//学号
cJSON*c_score=NULL;//C语言分数

/*创建一个JSON对象,{}扩起来*/
cJSON*obj=cJSON_CreateObject();
if(obj==NULL)
{
gotoend;
}

/*创建"name":"xxx"键值对*/
name=cJSON_CreateString(_Stu->name);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"name",name);

/*创建"num":207键值对*/
num=cJSON_CreateNumber(_Stu->num);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"num",num);

/*创建"c_score":95键值对*/
c_score=cJSON_CreateNumber(_Stu->c_score);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"c_score",c_score);

res_string=cJSON_Print(obj);//呈现为JSON格式
//res_string=cJSON_PrintUnformatted(obj);//呈现为无格式

if(res_string==NULL)
{
fprintf(stderr,"Failed to print monitor.
");
}

/*异常情况统一Delete(free)*/
end:
cJSON_Delete(obj);
returnres_string;
}

详细解释见注释。我们重点看一下cJSON_Print与cJSON_PrintUnformatted这两个接口。

这两个接口的差别就是组合成的JSON数据是否有空格。

有空格的JSON数据,即用cJSON_Print时的效果为:

bca850be-5b3b-11ee-939d-92fbcf53809c.png

无空格的JSON数据,即用cJSON_PrintUnformatted时的效果为:

bcb8c1a6-5b3b-11ee-939d-92fbcf53809c.png

如果想要输出查看时,当然是用cJSON_Print比较方便查看;如果是实际通信时,当然是用cJSON_PrintUnformatted会比较好,毕竟去掉空格就可以减小一定程度的通信负担。

完整代码:

/*
作者:ZhengN
公众号:嵌入式大杂烩
*/

#include
#include
#include
#include"cJSON.h"

#defineSTU_NAME_LEN32

/*学生结构体*/
typedefstruct_Student
{
charname[STU_NAME_LEN];//名字
intnum;//学号
intc_score;//C语言分数
}StudentDef,*pStudentDef;

/*内部函数声明*/
staticchar*StudentsData_Packet(pStudentDef _Stu);

/********************************************************************************************************
**函数:main
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
intmain(void)
{
charname[STU_NAME_LEN]={0};
intnum=0;
intc_score=0;
StudentDef stu;
intstu_count=0;
inti=0;

/*学生总人数*/
printf("Please input number of student:");
scanf("%d",&stu_count);

while(i++< stu_count)
    {
        /* 名字 */
        printf("Please input name: ");
        scanf("%s", name);
        if (strlen(name) < STU_NAME_LEN)
        {
            strncpy((char*)&stu.name, name, strlen(name)+1);
        }
        else
        {
            printf("The name is too long
");
        }
        
        /* 学号 */
        printf("Please input num (0~100): ");
        scanf("%d", &num);
        stu.num = num;

        /* C语言分数 */
        printf("Please input c_score (0~100): ");
        scanf("%d", &c_score);
        stu.c_score = c_score;

        /* 输出JSON格式的学生数据 */
        printf("%s
", StudentsData_Packet(&stu));
    }

    return 0;
}

/********************************************************************************************************
** 函数: StudentsData_Packet, 学生JSON格式数据组包
**------------------------------------------------------------------------------------------------------
** 参数: _Stu:组student json数据包需要的数据
** 说明: 
** 返回: JSON格式的字符串 
********************************************************************************************************/
static char *StudentsData_Packet(pStudentDef _Stu)
{
    char *res_string = NULL;    // 返回值
    cJSON *name = NULL;         // 名字
    cJSON *num = NULL;          // 学号
    cJSON *c_score = NULL;      // C语言分数

    /* 创建一个JSON对象,{}扩起来 */
    cJSON *obj = cJSON_CreateObject();
    if (obj == NULL)
    {
        goto end;
    }

    /* 创建 "name": "xxx" 键值对 */
    name = cJSON_CreateString(_Stu->name);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"name",name);

/*创建"num":207键值对*/
num=cJSON_CreateNumber(_Stu->num);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"num",num);

/*创建"c_score":95键值对*/
c_score=cJSON_CreateNumber(_Stu->c_score);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"c_score",c_score);

res_string=cJSON_Print(obj);//呈现为JSON格式
//res_string=cJSON_PrintUnformatted(obj);//呈现为无格式

if(res_string==NULL)
{
fprintf(stderr,"Failed to print monitor.
");
}

/*异常情况统一Delete(free)*/
end:
cJSON_Delete(obj);
returnres_string;
}

3、解析JSON数据包示例

我们把我们想要解析的数据放到一个student_data.txt文件中,然后读取其内容拿来解析,最后输出解析结果。

student_data.txt的内容如:

bcc62526-5b3b-11ee-939d-92fbcf53809c.png

解析结果:

bcccb490-5b3b-11ee-939d-92fbcf53809c.png

关于这个示例我们需要关注的接口有:

cJSON_Parse:JSON解析函数,解析{}得到里面的内容
cJSON_GetObjectItemCaseSensitive:从对象中获取键“字符串”。不分大小写
cJSON_IsString:判断是否是字符串
cJSON_IsNumber:判断是否是整形数
cJSON_Delete:JSON对象删除,做一些释放内存的工作

我们创建的解析函数如下:

staticvoidStudentsData_Parse(pStudentDef _Stu,constchar*_JsonStudnetData)
{
cJSON*student_json=NULL;//student_json操作对象,可代表{}扩起来的内容
cJSON*name=NULL;
cJSON*num=NULL;
cJSON*c_score=NULL;

/*开始解析*/
student_json=cJSON_Parse(_JsonStudnetData);
if(NULL==student_json)
{
constchar*error_ptr=cJSON_GetErrorPtr();
if(error_ptr!=NULL)
{
fprintf(stderr,"Error before:%s
",error_ptr);
}
gotoend;
}

/*解析获取name得值*/
name=cJSON_GetObjectItemCaseSensitive(student_json,"name");
if(cJSON_IsString(name)&&(name->valuestring!=NULL))
{
memcpy(&_Stu->name,name->valuestring,strlen(name->valuestring));
}

/*解析获取num的值*/
num=cJSON_GetObjectItemCaseSensitive(student_json,"num");
if(cJSON_IsNumber(num))
{
_Stu->num=num->valueint;
}

/*解析获取c_score的值*/
c_score=cJSON_GetObjectItemCaseSensitive(student_json,"c_score");
if(cJSON_IsNumber(c_score))
{
_Stu->c_score=c_score->valueint;
}

end:
cJSON_Delete(student_json);
}

解释见注释。

完整代码:

/*
作者:ZhengN
公众号:嵌入式大杂烩
*/
#include
#include
#include
#include"cJSON.h"

#defineSTU_NAME_LEN32

/*学生结构体*/
typedefstruct_Student
{
charname[STU_NAME_LEN];//名字
intnum;//学号
intc_score;//C语言分数
}StudentDef,*pStudentDef;

/*内部函数声明*/
staticvoidStudentsData_Parse(pStudentDef _Stu,constchar*_JsonStudnetData);
staticvoidPrintParseResult(constpStudentDef _Stu);

/********************************************************************************************************
**函数:main
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
intmain(void)
{
StudentDef stu={0};//保存解析后的数据
intfile_len=0;//文件长度
FILE*fp=NULL;//文件句柄
char*data=NULL;//用于保存从文件读出的数据

/*文件操作*/
if((fp=fopen("student_data.txt","r"))==NULL)
{
printf("Open file error!
");
exit(EXIT_FAILURE);
}
fseek(fp,0,SEEK_END);//文件位置指针指向文件末尾
file_len=ftell(fp);//获取文末相对于文首的偏移值
fseek(fp,0,SEEK_SET);//文件位置指针指向文首
data=(char*)malloc(file_len+1);//为data申请堆内存
fread(data,file_len,1,fp);//读取文件数据保存至data
fclose(fp);//关闭文件

/*解析*/
StudentsData_Parse(&stu,(constchar*)data);

/*打印输出解析结果*/
PrintParseResult(&stu);

/*释放内存*/
free(data);//防止内存泄漏
data=NULL;//防止出现野指针

return0;
}

/********************************************************************************************************
**函数:StudentsData_Parse,JOSN格式学生期末数据解析
**------------------------------------------------------------------------------------------------------
**参数:_JsonStudnetData:JSON数据_Stu:保存解析出的有用数据
**说明:
**返回:
********************************************************************************************************/
staticvoidStudentsData_Parse(pStudentDef _Stu,constchar*_JsonStudnetData)
{
cJSON*student_json=NULL;//student_json操作对象,可代表{}扩起来的内容
cJSON*name=NULL;
cJSON*num=NULL;
cJSON*c_score=NULL;

/*开始解析*/
student_json=cJSON_Parse(_JsonStudnetData);
if(NULL==student_json)
{
constchar*error_ptr=cJSON_GetErrorPtr();
if(error_ptr!=NULL)
{
fprintf(stderr,"Error before:%s
",error_ptr);
}
gotoend;
}

/*解析获取name得值*/
name=cJSON_GetObjectItemCaseSensitive(student_json,"name");
if(cJSON_IsString(name)&&(name->valuestring!=NULL))
{
memcpy(&_Stu->name,name->valuestring,strlen(name->valuestring));
}

/*解析获取num的值*/
num=cJSON_GetObjectItemCaseSensitive(student_json,"num");
if(cJSON_IsNumber(num))
{
_Stu->num=num->valueint;
}

/*解析获取c_score的值*/
c_score=cJSON_GetObjectItemCaseSensitive(student_json,"c_score");
if(cJSON_IsNumber(c_score))
{
_Stu->c_score=c_score->valueint;
}

end:
cJSON_Delete(student_json);
}

/********************************************************************************************************
**函数:PrintParseResult,打印输出解析结果
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
staticvoidPrintParseResult(constpStudentDef _Stu)
{
printf("name:%s,num:%d,c_score:%d
",_Stu->name,_Stu->num,_Stu->c_score);
}

二、综合示例

上一节中我们的组包、解析demo都是分开测试的,这一节再分享一个两个demo综合起来的demo:

bcd6c980-5b3b-11ee-939d-92fbcf53809c.png

运行演示:

bcdd8b26-5b3b-11ee-939d-92fbcf53809c.gif

bcf48f60-5b3b-11ee-939d-92fbcf53809c.png

bd139810-5b3b-11ee-939d-92fbcf53809c.png

json_print.c完整代码:

/*
作者:ZhengN
公众号:嵌入式大杂烩
*/
#include
#include
#include
#include
#include"cJSON.h"

#defineSTU_NAME_LEN32

/*学生结构体*/
typedefstruct_Student
{
charname[STU_NAME_LEN];//名字
intnum;//学号
intc_score;//C语言分数
}StudentDef,*pStudentDef;

/*内部函数声明*/
staticStudentDefStudentData_Prepare(void);
staticchar*StudentsData_Packet(pStudentDef _Stu);
staticvoidStudentData_Send(constchar*_data);

/********************************************************************************************************
**函数:main
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
intmain(void)
{
StudentDef stu={0};
char*stu_data=NULL;
intstu_count=0;
inti=0;

/*需要登记的学生总人数*/
printf("Please input number of student:");
scanf("%d",&stu_count);

while(i++< stu_count)
    {
        /* 准备数据 */
        stu = StudentData_Prepare();

        /* JSON格式数据组包 */
        stu_data = StudentsData_Packet(&stu);

        /* 发送数据 */
        StudentData_Send(stu_data);
    }

    return 0;
}

/********************************************************************************************************
** 函数: StudentData_Prepare, 准备组包需要的数据
**------------------------------------------------------------------------------------------------------
** 参数: 
** 说明: 
** 返回: 获取得到的数据
********************************************************************************************************/
static StudentDef StudentData_Prepare(void)
{
    char name[STU_NAME_LEN] = {0};
    int num = 0;
    int c_score = 0;
    StudentDef stu;

    /* 名字 */
    printf("Please input name: ");
    scanf("%s", name);
    if (strlen(name) < STU_NAME_LEN)
    {
        strncpy((char*)&stu.name, name, strlen(name)+1);
    }
    else
    {
        printf("The name is too long
");
    }
    
    /* 学号 */
    printf("Please input num (0~100): ");
    scanf("%d", &num);
    stu.num = num;

    /* C语言分数 */
    printf("Please input c_score (0~100): ");
    scanf("%d", &c_score);
    stu.c_score = c_score;

    return stu;
}

/********************************************************************************************************
** 函数: StudentsData_Packet, JSON格式数据组包
**------------------------------------------------------------------------------------------------------
** 参数: _Stu:组student json数据包需要的数据
** 说明: 
** 返回: JSON格式的字符串 
********************************************************************************************************/
static char *StudentsData_Packet(pStudentDef _Stu)
{
    char *res_string = NULL;    // 返回值
    cJSON *name = NULL;         // 名字
    cJSON *num = NULL;          // 学号
    cJSON *c_score = NULL;      // C语言分数

    /* 创建一个JSON对象,{}扩起来 */
    cJSON *obj = cJSON_CreateObject();
    if (obj == NULL)
    {
        goto end;
    }

    /* 创建 "name": "xxx" 键值对 */
    name = cJSON_CreateString(_Stu->name);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"name",name);

/*创建"num":207键值对*/
num=cJSON_CreateNumber(_Stu->num);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"num",num);

/*创建"c_score":95键值对*/
c_score=cJSON_CreateNumber(_Stu->c_score);
if(name==NULL)
{
gotoend;
}
cJSON_AddItemToObject(obj,"c_score",c_score);

res_string=cJSON_Print(obj);//呈现为JSON格式
//res_string=cJSON_PrintUnformatted(obj);//呈现为无格式

if(res_string==NULL)
{
fprintf(stderr,"Failed to print monitor.
");
}

/*异常情况统一Delete(free)*/
end:
cJSON_Delete(obj);
returnres_string;
}

/********************************************************************************************************
**函数:StudentData_Send,JSON格式字符串数据组包发送
**------------------------------------------------------------------------------------------------------
**参数:_data:要发送的数据
**说明:
**返回:
********************************************************************************************************/
staticvoidStudentData_Send(constchar*_data)
{
WSADATA wd;
  SOCKET ClientSock;
  SOCKADDR_INServerSockAddr;

printf("%s

",_data);

  /*初始化操作sock需要的DLL*/
  WSAStartup(MAKEWORD(2,2),&wd);

  /*向服务端发起请求*/
memset(&ServerSockAddr,0,sizeof(ServerSockAddr));
ServerSockAddr.sin_family=AF_INET;
ServerSockAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
ServerSockAddr.sin_port=htons(1314);

/*创建客户端socket*/
if(-1==(ClientSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
{
printf("socket error!
");
exit(EXIT_FAILURE);
}
if(-1==connect(ClientSock,(SOCKADDR*)&ServerSockAddr,sizeof(SOCKADDR)))
{
printf("connect error!
");
exit(EXIT_FAILURE);
}

/*发送数据到服务端*/
send(ClientSock,_data,strlen(_data),0);

/*关闭套接字*/
closesocket(ClientSock);
}

json_parse.c完整代码:

左右滑动查看全部代码>>>

/*
作者:ZhengN
公众号:嵌入式大杂烩
*/
#include
#include
#include
#include
#include"cJSON.h"

#defineSTU_NAME_LEN32

/*学生结构体*/
typedefstruct_Student
{
charname[STU_NAME_LEN];//名字
intnum;//学号
intc_score;//C语言分数
}StudentDef,*pStudentDef;

/*内部函数声明*/
staticchar*StudentsData_Recv(void);
staticvoidStudentsData_Parse(pStudentDef _Stu,constchar*_JsonStudnetData);
staticvoidPrintParseResult(constpStudentDef _Stu);
staticvoidSaveParseResult(constpStudentDef _Stu);

/*内部全局变量*/
staticFILE*stu_fp=NULL;

/********************************************************************************************************
**函数:main
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
intmain(void)
{
StudentDef stu={0};
char*recv_data;

while(1)
{
/*接收数据*/
recv_data=StudentsData_Recv();

/*解析*/
StudentsData_Parse(&stu,(constchar*)recv_data);

/*打印输出解析结果*/
PrintParseResult(&stu);

/*保存数据到文件*/
SaveParseResult(&stu);

/*释放内存*/
free(recv_data);//防止内存泄漏
recv_data=NULL;//防止出现野指针
}

return0;
}

/********************************************************************************************************
**函数:StudentsData_Recv,接收数据
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
staticchar*StudentsData_Recv(void)
{
WSADATA wd;
  SOCKADDR_IN ServerSockAddr;
intrecv_len=0;
char*recv_buf=(char*)malloc(512);
staticSOCKET ServerSock,ClientSock;
staticSOCKADDR ClientAddr;
staticintaddr_size=0;
staticintrun_count=0;

/*以下操作执行只一次就可以*/
if(0==run_count)
{
/*初始化操作sock需要的DLL*/
WSAStartup(MAKEWORD(2,2),&wd);

/*创建服务端socket*/
if(-1==(ServerSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
{
printf("server socket error!
");
exit(EXIT_FAILURE);
}

/*设置服务端信息*/
memset(&ServerSockAddr,0,sizeof(ServerSockAddr));//给结构体ServerSockAddr清零
ServerSockAddr.sin_family=AF_INET;//使用IPv4地址
ServerSockAddr.sin_addr.s_addr=inet_addr("127.0.0.1");//本机IP地址
ServerSockAddr.sin_port=htons(1314);//端口

/*绑定套接字*/
if(-1==bind(ServerSock,(SOCKADDR*)&ServerSockAddr,sizeof(SOCKADDR)))
{
printf("bind error!
");
exit(EXIT_FAILURE);
}

printf("bind ok!
");
/*进入监听状态*/
if(-1==listen(ServerSock,10))
{
printf("listen error!
");
exit(EXIT_FAILURE);
}
printf("listen ok!
");

addr_size=sizeof(SOCKADDR);
}

run_count++;

/*监听客户端请求,accept函数返回一个新的套接字,发送和接收都是用这个套接字*/
if(-1==(ClientSock=accept(ServerSock,(SOCKADDR*)&ClientAddr,&addr_size)))
{
printf("client socket error!
");
exit(EXIT_FAILURE);
}

/*接受客户端的返回数据*/
memset(recv_buf,0,512);
recv_len=recv(ClientSock,recv_buf,512,0);
printf("%s
",recv_buf);

/*关闭客户端套接字*/
closesocket(ClientSock);

/*返回获取得到JSON数据*/
return(char*)recv_buf;
}

/********************************************************************************************************
**函数:StudentsData_Parse,JOSN格式学生期末数据解析
**------------------------------------------------------------------------------------------------------
**参数:_JsonStudnetData:JSON数据_Stu:保存解析出的有用数据
**说明:
**返回:
********************************************************************************************************/
staticvoidStudentsData_Parse(pStudentDef _Stu,constchar*_JsonStudnetData)
{
cJSON*student_json=NULL;//student_json操作对象,可代表{}扩起来的内容
cJSON*name=NULL;
cJSON*num=NULL;
cJSON*c_score=NULL;

/*开始解析*/
student_json=cJSON_Parse(_JsonStudnetData);
if(NULL==student_json)
{
constchar*error_ptr=cJSON_GetErrorPtr();
if(error_ptr!=NULL)
{
fprintf(stderr,"Error before:%s
",error_ptr);
}
gotoend;
}

/*解析获取name得值*/
name=cJSON_GetObjectItemCaseSensitive(student_json,"name");
if(cJSON_IsString(name)&&(name->valuestring!=NULL))
{
memset(&_Stu->name,0,STU_NAME_LEN*sizeof(char));
memcpy(&_Stu->name,name->valuestring,strlen(name->valuestring));
}

/*解析获取num的值*/
num=cJSON_GetObjectItemCaseSensitive(student_json,"num");
if(cJSON_IsNumber(num))
{
_Stu->num=num->valueint;
}

/*解析获取c_score的值*/
c_score=cJSON_GetObjectItemCaseSensitive(student_json,"c_score");
if(cJSON_IsNumber(c_score))
{
_Stu->c_score=c_score->valueint;
}

end:
cJSON_Delete(student_json);
}

/********************************************************************************************************
**函数:PrintParseResult,打印输出解析结果
**------------------------------------------------------------------------------------------------------
**参数:
**说明:
**返回:
********************************************************************************************************/
staticvoidPrintParseResult(constpStudentDef _Stu)
{
printf("name:%s,num:%d,c_score:%d

",_Stu->name,_Stu->num,_Stu->c_score);
}

/********************************************************************************************************
**函数:SaveParseResult,保存解析结果
**------------------------------------------------------------------------------------------------------
**参数:_Stu:需要保存的数据
**说明:
**返回:
********************************************************************************************************/
staticvoidSaveParseResult(constpStudentDef _Stu)
{
charwrite_buf[512]={0};
staticintstu_count=0;

/*以可在文件末尾追加内容的方式打开文件*/
  if((stu_fp=fopen("ParseResult.txt","a+"))==NULL)
  {
   printf("Open file error!
");
   returnexit(EXIT_FAILURE);
  }

/*按指定格式写入文件*/
snprintf(write_buf,512,"name:%s,num:%d,c_score:%d
",_Stu->name,_Stu->num,_Stu->c_score);
size_tlen=fwrite((char*)write_buf,1,strlen(write_buf),stu_fp);

/*文件位置指针偏移*/
fseek(stu_fp,len*stu_count,SEEK_SET);
stu_count++;

/*关闭文件*/
fclose(stu_fp);
}

编译命令:

左右滑动查看全部代码>>>

gcc json_print.c cJSON.c-o json_print.exe-lwsocket32
gcc json_parse.c cJSON.c-o json_parse.exe-lwsocket32

综合demo加了socket相关代码,本篇笔记主要介绍JSON数据的组包及解析。






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    112

    文章

    16092

    浏览量

    177028
  • 嵌入式
    +关注

    关注

    5058

    文章

    18971

    浏览量

    301884
  • 数据通信
    +关注

    关注

    2

    文章

    426

    浏览量

    33721
  • Stu
    Stu
    +关注

    关注

    0

    文章

    2

    浏览量

    7295
  • JSON
    +关注

    关注

    0

    文章

    116

    浏览量

    6929

原文标题:嵌入式实用知识之JSON数据

文章出处:【微信号:玩点嵌入式,微信公众号:玩点嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于stm32单片机的cjsonc语言例程

    大家好,现在给大家提供一个基于stm32f030单片机的cjsonc语言例程。json是在互联网领域数据传输中较常用的协议,该协议比较轻量级也通俗易懂,在物联网快速发展的时代,物物与平台
    发表于 12-02 22:14

    LiteOS云端对接教程01-cJSON组件使用教程

    Notation,即 JS对象简谱,是一种轻量级的数据格式。它采用完全独立于编程语言的文本格式存储和表示数据,语法简洁、层次结构清晰,易于人阅读和编写,同时也易于机器解析和生成,有
    发表于 02-26 09:53

    cjson解析数据

    最近项目用到cjson解析数据,当解析的的数据比较长时,会
    发表于 01-12 06:14

    单片机如果不用cJSON会怎样呢

    /*处理网络数据的时候往往需要用到JSON数据格式,单片机如果不用cJSON,处理起来会非常吃力以下程序与注释讲解了cJSON在STM32
    发表于 02-21 07:31

    一文解读基于RTThread使用libcs​​v进行数据解析

    1、rtthread运行libcs​​v 的使用最近做一个,需要做数据存储化的。一开始是,使用数据生成的目标文件格式为项目名称,保存数据文件
    发表于 08-25 15:40

    如何避免在解析cJSON时一个函数内出现过多的if语句呢?

    ,说明我们的cJSON格式的报文有很多的同级对象,不同的对象对应不同的业务,所以我们应该以业务进行划分,尽量将不同的数据解析划分到对应的业务代码模块中去。而不是全部都放在一块,那样自
    发表于 11-10 16:55

    在MQTT中的TCP样例中,需要添加cjson解析代码并将获取到的数据输出出去,应该如何修改代码?

    NULL! ");}// 解析数据// char bssid[23] = {0};pJsonRoot = cJSON_GetObjectItem(pJsonRoot, "
    发表于 02-10 08:38

    在MQTT中的TCP样例中,如何添加cjson解析代码并将获取到的数据输出出去?

    NULL! ");}// 解析数据// char bssid[23] = {0};pJsonRoot = cJSON_GetObjectItem(pJsonRoot, "
    发表于 03-03 06:24

    在MQTT中的TCP样例中,如何添加cjson解析代码并将获取到的数据输出出去?

    ;, event->data_len, event->data);// 创建json数据解析对象pJsonRoot = cJSON_Parse(event->
    发表于 03-08 06:28

    RT-Thread使用cjson软件发送64位长整型数据

      开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源为0.2.2,rt-thread版本为4.1.1,cjson软件使用的版本
    发表于 03-13 15:54

    用Delphi数据库开发

    用Delphi数据库开发:实验三 用Delphi数据库开发一、实验目的通过使用Delphi中BDE连接SQL数据库,掌握Delphi环境
    发表于 05-10 11:05 44次下载

    STM32F103C8T6移植cJSON解析JSON数据包

    /*处理网络数据的时候往往需要用到JSON数据格式,单片机如果不用cJSON,处理起来会非常吃力以下程序与注释讲解了cJSON在STM32
    发表于 12-27 18:29 27次下载
    STM32F103C8T6移植<b class='flag-5'>cJSON</b><b class='flag-5'>解析</b>JSON<b class='flag-5'>数据包</b>

    ZigBee3.0数据包解析

    ZigBee3.0是ZigBee联盟推出的可以互联互通的标准协议,用之前的Packet Sniffer抓包工具是无法解析ZigBee3.0的数据包,因ZigBee3.0的安全机制所有的数据包都是加密
    发表于 02-28 11:48 2632次阅读
    ZigBee3.0<b class='flag-5'>数据包</b><b class='flag-5'>解析</b>

    Oracle数据库ASM磁盘掉线的数据恢复案例

    数据库故障: Oracle数据库的ASM磁盘掉线,ASM实例不能挂载。管理员尝试修复数据库但是没有成功。 数据库
    的头像 发表于 03-03 13:42 902次阅读
    Oracle<b class='flag-5'>数据库</b>ASM磁盘<b class='flag-5'>组</b>掉线的<b class='flag-5'>数据</b>恢复案例

    RT-Thread使用cjson软件发送64位长整型数据

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源为0.2.2,rt-thread版本为4.1.1,cjson软件使用的版本是latest。
    的头像 发表于 10-11 15:09 858次阅读
    RT-Thread使用<b class='flag-5'>cjson</b>软件<b class='flag-5'>包</b>发送64位长整型<b class='flag-5'>数据</b>