最近iot code要跑在linux上,因为后面还要把它移植到公司自己的操作系统上(只支持C)就带来了一些麻烦,和nodeserver通信协议都是用JSON格式,所以这就涉及到了C语言对JSON的处理。CJSON 仅有头文件和C文件,不用编译依赖库,可以比较方便嵌入进去。CJSON比较好用,可以直接读sample就可以用了。
CJSON:项目地址
https://github.com/DaveGamble/cJSON
1 下载相应代码
git clone https://github.com/DaveGamble/cJSON
将cJSON.c 和 cJSON.h复制目标文件夹下
2 CJSON 关键类型
2.1 cJSON
cJSON represents JSON data using the cJSON struct data type:
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
int type;
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
double valuedouble;
char *string;
} cJSON;
关于JSON值的类型通过type值来判断,该类型被存储在bit-flag。我们通过cJSON_Is..先判断该key是否为空,在判断该值的类型。
2.2 创建数据
对于每种值类型,都有一个cJSON_Create…可用于创建该类型项的函数。所有这些都将分配一个cJSON稍后可以删除的结构cJSON_Delete。请注意,您必须在某些时候删除它们,否则会出现内存泄漏。如果已将项添加到数组或对象中,则不能将其删除cJSON_Delete。将其添加到数组或对象会转移其所有权,以便在删除该数组或对象时,它也会被删除。即只需要删除主要的那个json结构即可。最主要用到的就是创建对象cJSON_CreateObject,其他类型通过add相关操作创建。
2.3 添加数据
对于对象或数组而言,CJSON提供了cJSON_Add..用于向对象或者数组内添加成员
2.4 解析
提供了cJSON_GetObjectItemCaseSensitive接口用于层层解JSON。如果得到具体值可以使用cJSON_IsString等方法判断类型并访问color->valuestring得到相应的属性得到该类型的值。
3 sample
3.1 待处理JSON
{
state:{
color:red,
power:1
},
time:”18-07-23”
}
3.2 sample code
#include <stdio.h>
#include <cJSON.h>
// {
// state:{
// color:red,
// power:1
// },
// time:"18-07-23"
// }
//gcc cJSON.c test.c -I . -o test
char *JSONStringify(void)
{
char *string = NULL;
cJSON *monitor = cJSON_CreateObject();
cJSON *state = cJSON_CreateObject();
cJSON *time = cJSON_CreateObject();
char str[]="red";
if (cJSON_AddNumberToObject(state, "power", 1) == NULL)
goto end;
if (cJSON_AddStringToObject(state, "color", str) == NULL)
goto end;
cJSON_AddItemToObject(monitor, "state", state);
if (cJSON_AddStringToObject(monitor, "time", "18-07-23") == NULL)
goto end;
string = cJSON_PrintUnformatted(monitor);//紧凑型JSON
if (string == NULL)
fprintf(stderr, "Failed to print monitor.\n");
end:
cJSON_Delete(monitor);
return string;
}
int parseCMDJSON(const char* const monitor)
{
const cJSON *state = NULL;
const cJSON *time = NULL;
const cJSON *color = NULL;
const cJSON *power = NULL;
int status = 0;
cJSON *monitor_json = cJSON_Parse(monitor);
if (monitor_json == NULL)
{
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL)
printf("Error before: %s\n", error_ptr);
status = 0;
goto end;
}
time = cJSON_GetObjectItemCaseSensitive(monitor_json, "time");
if (!cJSON_IsNull(time) && cJSON_IsString(time) && (time->valuestring != NULL))
printf("time:\"%s\"\n", time->valuestring);
state = cJSON_GetObjectItemCaseSensitive(monitor_json, "state");
color = cJSON_GetObjectItemCaseSensitive(state, "color");
if (!cJSON_IsNull(color) && cJSON_IsString(color) && (color->valuestring != NULL))
printf("color:\"%s\"\n", color->valuestring);
power = cJSON_GetObjectItemCaseSensitive(state, "power");
if (!cJSON_IsNull(power) && cJSON_IsNumber(power))
printf("power:\"%d\"\n", power->valueint);
end:
cJSON_Delete(monitor_json);
return status;
}
int main(void){
char *str = JSONStringify();
printf("\n%s\n", str);
parseCMDJSON(str);
return 0;
}
3.3 测试
Test.c和cJSON.c和cJSON.h放到同一级目录下:
编译:gcc cJSON.c test.c -I . -o test
输出:
{“state”:{“power”:1,”color”:”red”},”time”:”18-07-23”}
time:”18-07-23”
color:”red”
power:”1”