网站服务器++免费,好看的wordpress文章模板下载,ppt插件 网站,网站开发基础培训点击蓝字关注我们因公众号更改推送规则#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络#xff0c;侵删前言json是目前最为流行的文本数据传输格式#xff0c;特别是在网络通信上广泛应用#xff0c;随着物联网的兴起#xff0c;在嵌入式设备上请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络侵删前言json是目前最为流行的文本数据传输格式特别是在网络通信上广泛应用随着物联网的兴起在嵌入式设备上也需要开始使用json进行数据传输那么如何快速简洁地用C语言进行json的序列化和反序列化呢当前应用最广泛的C语言json解析库当属cJSON但是使用cJSON读json进行序列化和反序列化需要根据key一个一个进行处理会导致代码冗余逻辑性不强哪有没有更好的方法呢思路在Android平台一般会使用gson等工具解析json这些工具将json直接映射成对象在C语言上使用对象的概念我们需要借助结构体然而最大的问题在于C语言没有高级语言具有的反射机制直接从json映射到结构体对象几乎是不可能的。怎么解决呢既然C语言没有反射机制那么我们可以自己定义一套类似于反射的机制这里我将其称之为结构体数据模型在数据模型中我们需要准确地描述结构体的特征包括结构体各成员的名称类型在结构体中的偏移。有了这些我们可以在解析josn的时候将解析得到的数据直接写入到对应的内存里面去或者是在序列化的时候直接从对应的内存中读取数据进行处理。实现CSON正是采用上面说到的思路使用数据模型对结构体进行描述然后基于cJSON根据数据模型进行解析将解析得到的数据直接写入到对应的内存区域从而实现从json到结构体对象的映射。CSON最基本的数据模型定义如下typedef struct cson_model
{CsonType type; /** 数据类型 */char *key; /** 元素键值 */short offset; /** 元素偏移 */
} CsonModel;通过type描述结构体成员的数据类型key描述该成员在json中对应的字段offset描述该结构体成员在结构体中的偏移CSON在解析json的时候根据type调用相应的cJSON API并传递key作为参数得到解析出的数据然后根据offset将数据写入到对应的内存空间。比如说这样一个结构体struct project
{int id;char *name;
}该结构体包含两个成员对于成员id我们使用数据模型对其进行描述{.typeCSON_TYPE_CHAR, keyid, offset0}对于结构体的每个成员都进行数据模型的定义就可以得到一个完整的结构体数据模型CSON会根据这个模型进行解析。因为是通过直接写内存的方式所以在写不同类型的量到内存中时会多次用到强制转型导致CSON中赋值的代码都类似于*(int *)((int)obj model[i].offset) (int)csonDecodeNumber(json, model[i].key);当然上面说到的数据模型只适用于基本数据类型的数据对于子结构体链表数组等需要对数据模型的定义进行扩充有兴趣的朋友可以直接阅读CSON源码。CSON使用实例声明结构体/** 项目结构体 */
struct project
{int id;char *name;
};/** 仓库结构体 */
struct hub
{int id;char *user;struct project *cson;
};定义数据模型对每一个需要使用cson的结构体都需要定义相对应的数据模型/** 项目结构体数据模型 */
CsonModel projectModel[]
{CSON_MODEL_OBJ(struct project),CSON_MODEL_INT(struct project, id),CSON_MODEL_STRING(struct project, name),
};/** 仓库结构体数据模型 */
CsonModel hubModel[]
{CSON_MODEL_OBJ(struct hub),CSON_MODEL_INT(struct hub, id),CSON_MODEL_STRING(struct hub, user),CSON_MODEL_STRUCT(struct hub, cson, projectModel, sizeof(projectModel)/sizeof(CsonModel))
};使用CSON解析只需要定义好数据模型就可以使用CSON读json进行序列化和反序列化void csonDemo(void)
{char *jsonDemo {\id\: 1, \user\: \Letter\, \cson\: {\id\: 2, \name\: \cson\}};/** 解析json */struct hub *pHub csonDecode(jsonDemo, hubModel, sizeof(hubModel)/sizeof(CsonModel));printf(hub: id: %d, user: %s, project id: %d, project name: %s\r\n,pHub-id, pHub-user, pHub-cson-id, pHub-cson-name);/** 序列化对象 */char *formatJson csonEncodeFormatted(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));printf(format json: %s\r\n, formatJson);/** 释放结构体对象 */csonFree(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));/** 释放序列化生成的json字符串 */csonFreeJson(formatJson);
}运行结果hub: id: 1, user: Letter, project id: 2, project name: cson
format json: {id: 1,user: Letter,cson: {id: 2,name: cson}
}可以看到无论是解析json还是序列化结构体到json在使用CSON的情况下都只需要一行代码就可以解决同样的操作在使用原生cJSON的情况下你可能需要多次判断解析元素。CSON地址❝https://github.com/NevermindZZT/cson如果你年满18周岁以上又觉得学【C语言】太难想尝试其他编程语言那么我推荐你学Python现有价值499元Python零基础课程限时免费领取限10个名额▲扫描二维码-免费领取戳“阅读原文”我们一起进步