项目准备一之CJSON使用
注:本文系湛江市第十七中学星火创客团队及岭南师范学院物联网俱乐部原创部分训练项目,转载请保留声明。
前言
今天是闭关的的第56天,项目已经完成,今天特地抽时间来总结一下这个项目的具体知识点。对即将到来的秋招,我们一起加油!!!!
一、JSON概念
·json指的是JavaScript对象表示法(JavaScript Object Notation)
·josn是轻量级的文本数据交换格式
·json独立于语言
·json具有自我描述性,更易理解
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,可以把JSON的结构理解成无序的、可嵌套的key-value键值对集合,这些key-value键值对以结构体或数组的形式来组织的。同一级的key-value键值对之间用一个,(逗号)隔开,每个key-value键值对是由一个key后面紧接一个:(冒号),冒号后面是这个key对应的value。key是一个word,由大小写字母、下划线及数字组成,可以由双引号封闭,也可以不用双引号。而value的取值集为:number、boolean(true、false)、null、string、object和array。
二、CJSON介绍
cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。
那么我们为什么选择cJSON来解析JSON字符串那?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.C文件和一个.h文件!并且文件体积大小不到K。源码思路也非常清晰,也非常适合研究。
我们可以通过此链接下载cJOSN,当我们下载好cJSON只需要把.C文件和.h文件包含文件拷贝到我们工程目录下,我们就可以使用了。cJSON的核心结构体就是一个cJSON,理解了这个结构体,基本上对cJSON的使用就有了个基本概念了,该结构体具体定义如下:
typedef struct cJSON {
struct cJSON*next,*prev; /* 遍历数组或对象链的前向或后向链表指针*/
struct cJSON *child; /*数组或对象的孩子节点*/
int type; /* key的类型*/
char *valuestring; /*字符串值*/
int valueint; /* 整数值*/
double valuedouble; /* 浮点数值*/
char *string; /* key的名字*/
} cJSON;
说明:
①cJSON是使用链表来存储数据的,其访问方式很像一棵树。每一个节点可以有兄弟节点,通过next/prev指针来查找,
它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。只有节点是对象或数组时才可
以有孩子节点。
②type是键(key)的类型,一共有种取值,分别是:False,True,null,Number,String,Array,Object。
若是Number类型,则valueint或valuedouble种存储着值,如期望的是int,则访问valueint,如期望的是double,
则访问valuedouble,可以得到值。
③若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。
string中存放的是这个节点的名字,可以理解位key的名称。
三、CJSON函数简介
CJSOM源码主要包括两个文件cjson.c以及cjson.h,其中cjson.h文件中包含了对于JSON格式的结构体定义以及一些操作JSON格式的功能函数,包括创建JSON、向JSON格式中添加数字,字符,布尔值等等、读取JSON格式、将JSON格式转化为字符串等,而cjson.c中就是功能函数的具体实现。
3.1 CJSON打包
1、cJSON *cJSON_CreateObject();
创建一个json对象,返回一个cJSON结构体类型的指针。
2、cJSON *cJSON_CreateArray();
创建一个数组对象,返回一个cJSON结构体类型的指针。
3、cJSON *cJSON_CreateString(const char *string);
创建一个字符串对象,传入一个char *类型的字符串,返回一个cJSON结构体类型的指针。
4、void cJSON_AddItemToArray(cJSON *array, cJSON *item);
向数组对象中添加一个元素,传入参数array为cJSON *结构体类型的指针,为数组对象,item为添加如数字对象中
的对象指针。
5、void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
向json对象中添加一对元素,object为json对象,string为加入一对元素中的name,item为加入一对元素中的value。
6、char *cJSON_Print(cJSON *item);
将一个cJSON结构体代表的json对象转换为一个json格式的字符串。
7、void cJSON_Delete(cJSON *c)
释放一个cJSON对象占用的内存空间。
3.2 CJSON解析
cJSON *cJSON_Parse(const char *value);
作用:将一个JSON数据包,按照cJSON结构体序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体。
返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL。
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
作用:获取JSON字符串字段值
返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL
char *cJSON_Print(cJSON *item);
作用:将cJSON数据解析成JSON字符串,并在堆中开辟一块char *的内存空间存储JSON字符串
返回值:成功返回一个char*指针该指针指向位于堆中JSON字符串,失败返回NULL
void cJSON_Delete(cJSON *c);
作用:释放位于堆中cJSON结构体内存
返回值:无
四、代码演示(解析)
以下为本人在项目实现之前学习的代码,主要为借鉴与自我编写得来,请大家以批评的态度来学习,如有建议可留言,我将不胜感激。
4.1 创建json文件
{
"date" : "2021年8月7号",
"time" : "18:09",
"fx" : "东风",
"type" : "晴天",
"sentence": "在这个时代,我们除了胜利别无选择!"
}
4.2 解析json文件
#include <stdio.h>
#include "cJSON.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
cJSON *value;
char *data;
//打开JSON数据文件
int fd = open("../file/data.json",O_RDWR);
if(fd < 0)
{
perror("open fail\n");
return -1;
}
//读取文件中的数据
char buf[2048]={0};
int ret = read(fd, buf, sizeof(buf));
if(ret == -1)
{
perror("read error");
return -1;
}
//关闭文件
close(fd);
//把该字符串数据转换成JSON对象
cJSON *root=cJSON_Parse(buf);
if(root == NULL)
{
printf("parse error\n");
return -1;
}
/***************************data获取*********************************/
//根据key值去获取对应的value
value = cJSON_GetObjectItem(root,"date");
if(value == NULL)
{
printf("GetObjec error\n");
return -1;
}
//把数据转成 字符串输出
data = cJSON_Print(value);
printf("data=%s\n",data);
/****************************fx获取**********************************/
value = cJSON_GetObjectItem(root,"fx");
if(value == NULL)
{
printf("GetObjec error\n");
return -1;
}
//把数据转成 字符串输出
data = cJSON_Print(value);
printf("fx=%s\n",data);
/*****************************type获取*********************************/
//根据key值去获取对应的value
value = cJSON_GetObjectItem(root,"type");
if(value == NULL)
{
printf("GetObjec error\n");
return -1;
}
//把数据转成 字符串输出
data=cJSON_Print(value);
printf("type=%s\n",data);
/*****************************sentence获取*********************************/
//根据key值去获取对应的value
value = cJSON_GetObjectItem(root,"sentence");
if(value == NULL)
{
printf("GetObjec error\n");
return -1;
}
//把数据转成 字符串输出
data=cJSON_Print(value);
printf("sentence=%s\n",data);
return 0;
}
4.2 运行效果图
五、项目总结
json打包与解析,是完成项目的重要部分,因为需要将数据打包上传到云端,而当云端下发指令后,树莓派需要对指令进行解析,提取关键词,通过过对比完成相应的操作。以上的代码为解析,如果需要看json打包的代码,请点击头像进入到我的空间里面,寻找整个项目的博客,里面会附有源码。