写此json数据解析库的主要原因,因为最近在看json相关的程序,发现在linux下有完整的json库,而查看了这个json库后发现,这种json-c的库并不适用于单片机系统,尤其是没有OS的单片机系统,里面对内存的开销很大,大量使用了malloc()和free()函数进行内存分配,考虑到在单片机系统内,这写函数都是尽量不使用,同时内存并不多,出于爱好,先写了个基于纯C语言的简单的json解析库。
该库具备的特性:
1.能够解析json字符串内的子json数据。
2.能够解析str类型的json数据
3.能够解析INT型数据
4.能够解析bool型数据
暂不支持的特性:
1.不支持解析json数组类型数据(若去解析json数据中存在数组类型数据,将会返回出错)(json数组在单片机中用得确实少)
2.不支持内存不够的判断(在使用API时需要保证所给的buff能够装得下所解析的数据,这也是单片机中常用的做法)
3.基本库所解析回来的INT,bool等数据类型都是字符串的形式存在,可以通过扩张库转化为数字和bool变量
eg:例程使用了linux下的json-c生成了一段json字符串,然后调用我编写的json解析获取数据
#include
#include
#include
#include "json.h"
#include "hgetjson.h" //针对于单片机提供的json库头文件
int main(int argc, char *argv[])
{
json_object *smart_home_protocol = NULL, *hellotest = NULL, *test11 = NULL;
smart_home_protocol = json_object_new_object();
hellotest = json_object_new_object();
test11 = json_object_new_object();
if(smart_home_protocol == NULL)
{
printf("New Json Object Fail!\n");
exit(1);
}
int rc = json_object_object_add(smart_home_protocol, "Smart Home", smart_home_protocol);
json_object_object_add(smart_home_protocol, "heihei", json_object_new_int(66));
json_object_object_add(test11, "haha", json_object_new_int(35));
json_object_object_add(hellotest, "test0", hellotest);
json_object_object_add(hellotest, "haha",json_object_new_int(36));
json_object_object_add(hellotest, "heihei", test11);
json_object_object_add(smart_home_protocol, "test", hellotest);
//if (rc != -1)
//{
//printf("ERROR: able to successfully add object to itself!\n");
//fflush(stdout);
//}
json_object_object_add(smart_home_protocol, "router", json_object_new_string("Normal"));
json_object_object_add(smart_home_protocol, "temperature", json_object_new_int(36));
json_object_object_add(smart_home_protocol, "haha",json_object_new_int(37));
json_object_object_add(smart_home_protocol, "safe", json_object_new_boolean(1));
char *jsonstr = json_object_to_json_string(smart_home_protocol);
printf("Json data :%s\n", jsonstr); //linux json-c 生成的json字符串
char buff1[50] = {0}; //用来存放数据的buff
char buff2[50] = {0};
int ret = get_json_object(buff1, "test", jsonstr); //从jsonstr中获取名称为test的子json数据
if(ret)
printf("ERROR\n");
else
{
printf("\ntest json from jsonstr:%s\n", buff1);
}
ret = get_json_object(buff2, "heihei", buff1); //从子testjson中获取名为heihei的子json数据
if(ret)
printf("ERROR\n");
else
{
printf("\nheihei json from test:%s\n", buff2);
}
ret = get_json_object(buff1, "heihei", jsonstr); //直接从jsonstr获取名为heihei的子json数据,直接穿过test 的子json
if(ret)
printf("ERROR\n");
else
{
printf("\nheihei json from jsonstr:%s\n", buff1);
}
const char testname[4][10] = {"heihei", "haha", "router", "safe"};
printf("\n");
for(int ii = 0; ii < 4; ii++) //获取不同的数据和数据类型
{
ret = get_json_dat(buff2, &testname[ii][0], jsonstr);
if(ret == STRTYPE)
printf("%s is STR dat from jsonstr, dat is %s\n", &testname[ii][0], buff2);
else if(ret == INTTYPE)
printf("%s is INT dat from jsonstr, dat is %s\n", &testname[ii][0], buff2);
else if(ret == BOOLTYPE)
printf("%s is BOOL dat from jsonstr, dat is %s\n", &testname[ii][0], buff2);
else
printf("Get ERROR\n");
}
json_object_put(smart_home_protocol); //释放掉linux json-c的内存
return 0;
}
运行结果如图:
单片机hjson使用说明:
获取json数据中子json API
int get_json_object(char *buff, char *object_name, char *json_dat)
buff:用于保存解析后的数据存储指针
object_name:获取子json数据名称指针
json_dat:原始json数据指针
返回值:0,获取成功,1获取失败
获取json内部数据的API:
int get_json_dat(char *buff, char *dat_name, char *json)
buff:用于保存解析后的数据存储指针
dat_name:获取数据的名称指针
json:原始json数据(注意:获取数据只会从根json中获取,不会从内部包含的子json中回去数据,若需要获取子json中的数据,需要先把子json给提取出来)
返回值:#define NONETYPE 0
#define STRTYPE 1
#define INTTYPE 2
#define BOOLTYPE 3
返回-1,者是没有找到该数据
源码见:
V1.0版本
https://download.csdn.net/download/qq_18604707/10741372
V1.1 处理了个别情况下字符串类型读取数据不正确的问题
https://download.csdn.net/download/qq_18604707/12419134