C语言编程--cjson库应用
文章摘要: 本文主要对单片机及Linux中对cjson库的应用,进行了详细说明。
通过验证,对于封装json格式,调用cjson库并不好用,还不如sprintf拼接更省事,特别对于浮点型小数,解析格式倒是不错。
Linux应用
安装cjson库:
sudo apt-get install libcjson-dev
编译选项: -lcjson
单片机:
下载cjson源码:https://github.com/arnoldlu/cJSON
只需将cJSON.h/cJSON.c代码加入工程编译即可。
cJSON_CreateObject():创建一个json数据结点;
cJSON_AddStringToObject():添加一个字符串数据;
cJSON_AddNumberToObject():添加一个数值数据;
cJSON_AddItemToObject():添加一个json项目;
cJSON_CreateArray():添加一个json数组;
cJSON_Print():转换json数据为字符串;
cJSON_Delete():销毁json数据,注意通过cJSON_Parse()创建的json数据中分配了堆存储,必须通过cJSON_Delete()注销才能释放空间;
示例代码: encode.c
#include <stdio.h>
#include "cJSON.h"
int main()
{
cJSON * root = cJSON_CreateObject();
cJSON * item = cJSON_CreateObject();
cJSON * next = cJSON_CreateObject();
// 根节点下添加
cJSON_AddItemToObject(root, "rc", cJSON_CreateNumber(0));
cJSON_AddItemToObject(root, "operation", cJSON_CreateString("CALL"));
cJSON_AddItemToObject(root, "service", cJSON_CreateString("telephone"));
cJSON_AddItemToObject(root, "text", cJSON_CreateString("打电话给张三"));
//root节点下添加semantic子节点
cJSON_AddItemToObject(root, "semantic", item);
//semantic节点下添加item子节点
cJSON_AddItemToObject(item, "slots", next);
//添加name节点
cJSON_AddItemToObject(next, "name", cJSON_CreateString("张三"));
printf("%s\n", cJSON_Print(root));
return 0;
}
执行结果:
{
"rc": 0,
"operation": "CALL",
"service": "telephone",
"text": "打电话给张三",
"semantic": {
"slots":{
"name": "张三"
}
}
}
decode.c
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
// 以递归的方式打印json的最内层键值对
void printJson(cJSON * root)
{
for(int i=0; i<cJSON_GetArraySize(root); i++) //遍历最外层json键值对
{
cJSON * item = cJSON_GetArrayItem(root, i);
if(cJSON_Object == item->type) //如果对应键的值仍为cJSON_Object就递归调用printJson
{
printf("----------------------\r\n");
printJson(item); // 递归
}
else //值不为json对象就直接打印出键和值
{
printf("%s->", item->string);
printf("%s\n", cJSON_Print(item));
}
}
}
int main()
{
char * jsonStr = "{\"semantic\":{\"slots\":{\"name\":\"张三\"}}, \"rc\":0, \"operation\":\"CALL\", \"service\":\"telephone\", \"text\":\"打电话给张三\"}";
cJSON * root = NULL;
cJSON * item = NULL;//cjson对象
root = cJSON_Parse(jsonStr);
if (!root)
{
printf("Error before: [%s]\n",cJSON_GetErrorPtr());
}
else
{
printf("%s\n", "有格式的方式打印Json:");
printf("%s\n\n", cJSON_Print(root));
#if 0
printf("%s\n", "无格式方式打印json:");
printf("%s\n\n", cJSON_PrintUnformatted(root));
#endif
printf("%s\n", "一步一步的获取name 键值对:");
printf("%s\n", "获取semantic下的cjson对象:");
item = cJSON_GetObjectItem(root, "semantic");//
printf("%s\n", cJSON_Print(item));
printf("%s\n", "获取slots下的cjson对象");
item = cJSON_GetObjectItem(item, "slots");
printf("%s\n", cJSON_Print(item));
printf("%s\n", "获取name下的cjson对象");
item = cJSON_GetObjectItem(item, "name");
printf("%s\n", cJSON_Print(item));
printf("%s:", item->string); //看一下cjson对象的结构体中这两个成员的意思
printf("%s\n", item->valuestring);
printf("\n%s\n", "打印json所有最内层键值对:");
printJson(root);
}
return 0;
}