C++轻量级Json解析工具—TinyJson
C++轻量级Json解析工具—TinyJson
简介
之前Json解析工具习惯于用**nlohmann/json**,后来发现要兼容Centos5系的系统,且需要批量使用,系统升级gcc/g++升级有点不现实,后来改用轻量级TinyJson库,说一下在使用碰到的一些问题以及为了兼容性作出的修改。
TinyJson轻量级json解析工具,只需要包含头就可以直接使用。兼容Windows/Linux平台。Mac并没有进行相关测试。理论上兼容。
TinyJson相关信息
Git地址:https://github.com/button-chen/tinyjson
相关介绍,在github并没有过的介绍,但是在百度的时候发现了很多关于TinyJson的介绍,有点乱,不一一细究了。
- 使用样例
在github中有相关的一些介绍,不做详细介绍。
测试缺陷
1.兼容C++03 编译
Lamba表达式的去除
char LastValidChar(std::string json,int index)
{for (int i = index - 1; i >= 0; --i) {if (isspace(json[i])) continue;char tmp = json[i];return tmp;}return '\0';
}
//-------------------------------------------------------------//
//将下方的lamba表达式注释掉,并改为添加上的函数//
// 解析为 key-value 调用一次解析一个层次
inline bool ParseJson::ParseObj(std::string json) {//------注释区域--------------//auto LastValidChar = [&](int index)->char{for (int i = index-1; i >= 0; --i){if (isspace(json[i])) continue;char tmp = json[i];return tmp;}return '\0';};//---------------------------//
else if (isdigit(nextc) && LastValidChar(json,i) == ':')
//-----------------修改----------------------------//
//---LastValidChar(i) --LastValidChar(json,i)-----//
else if (isdigit(nextc) && LastValidChar(i) == ':')
{tokens = FetchNumStr(json, i, offset);
}
2.不支持数组的读取
测试demo
std::string data = "{\"type\": \"cdk\",\"cdk\":\"18000002\",\
\"frist_reward_goods\":[\
[\"1\",\"3037\",\"100\"],\
[\"2\",\"3037\",\"100\"],\
[\"3\",\"3037\",\"100\"],\
[\"4\",\"3037\",\"100\"]]}";
TinyJson在读取的时候,数组只显示为字符串,无论 tiny::xarray还是 tiny::xobject 都无法解析。后来就做了修改。
tiny::xarray arry;
get_value(j, std::string("frist_reward_goods"), arry);
结果如下图:
根据读取结果,处理结果无法使用。数组元素读取结果,把[]符号都加入进去还是读取很失败。
修改如下:
/*
函数名:字符串切割子函数
srcStr:源字符串
delimStr:分割符字符串
repeatedCharIgnored:是否支持分割符字符串合并
return:切割后的字符串Vector
*/
std::vector<std::string> splitString(std::string srcStr, std::string delimStr, bool repeatedCharIgnored)
{std::vector<std::string> resultStringVector;std::replace_if(srcStr.begin(), srcStr.end(), [&](const char& c) {if (delimStr.find(c) != std::string::npos) { return true; } else { return false; }}/*pred*/, delimStr.at(0));//将出现的所有分隔符都替换成为一个相同的字符(分隔符字符串的第一个)size_t pos = srcStr.find(delimStr.at(0));std::string addedString = "";while (pos != std::string::npos) {addedString = srcStr.substr(0, pos);if (!addedString.empty() || !repeatedCharIgnored) {resultStringVector.push_back(addedString);}srcStr.erase(srcStr.begin(), srcStr.begin() + pos + 1);pos = srcStr.find(delimStr.at(0));}addedString = srcStr;if (!addedString.empty() || !repeatedCharIgnored) {resultStringVector.push_back(addedString);}return resultStringVector;
}
/*
字符串数组获取
in j:Json对象
int key:Json键值
output value 字符串数组
--利用 key,获取数组字符串。'['数组元素的开始,'],'为一个字符串数组的结束。判断'],'来划分数组。内部以','来划分,子相元素。
*/
static void get_value(tiny::TinyJson j, std::string key, std::vector<std::vector<std::string>> &value){std::string object = j.Get<std::string>(key);int i = 1;while ( i < object.length() - 1){std::vector<std::string> item;if (object[i] == '['){std::string item_string;i++;while (object[i] != ']' && object[i] != '['){if (object[i] != ',' && object[i] != '"' && object[i] != ' '){item_string += object[i];}else if (object[i] == ',' || ( object[i] == '"'&& object[i+1] == ']')){item.push_back(item_string);item_string = "";}i++;}}if(!item.empty())value.push_back(item);i++;}}
处理结果如下所示:
std::vector<std::vector<std::string>> vec;
get_value(j, std::string("frist_reward_goods"), vec);
3.相连Key和value的获取
在实际使用中,发现相连的key和value如果相同,返回的value为下一个key值。
demo:type的值为cdk,cdk的值为18000002
"type\": \"cdk\",\"cdk\":\"18000002\"
std::string cdk;
get_value(j,std::string("cdk"),cdk);
处理结果如下图:
原因:
原处理函数为:
template<typename R>
R Get(std::string key, R defVal) {auto itr = std::find(KeyVal_.begin(), KeyVal_.end(), key);if (itr == KeyVal_.end()) {return defVal;}return Value(*(++itr)).GetAs<R>();
}
使用了std::find()方法,find的定义为返回第一个找到的元素。这里并没有做返回的值是否为key还是value,所以出现了这个错误,修改如下,或元素的类型判断。根据json key和value一一对应的关系,可以判断value为偶数为,从0开始计数,value为奇数位。所以修改如下,手动遍历。
template<typename R>
R Get(std::string key, R defVal) {auto itr = KeyVal_.begin();int i = 0;for (itr; itr != KeyVal_.end(); itr++){if (key == (*itr) && !(i % 2))break;i++;}if (itr == KeyVal_.end()) {return defVal;}return Value(*(++itr)).GetAs<R>();
}
运行结果如下:
cdk:18000002
封装
头文件调用
#include <iostream>
#include <string>
#include <vector>
#include "tinyjson.hpp"
//类的封装
class Json
{
public:static tiny::TinyJson parse(std::string data){tiny::TinyJson json;json.ReadJson(data);return json;}static void get_value(tiny::TinyJson j, std::string key, std::string &value){value = j.Get<std::string>(key);}static void get_value(tiny::TinyJson j, std::string key, tiny::xarray &value){value = j.Get<tiny::xarray>(key);}static void get_value(tiny::TinyJson j, std::string key, std::vector<std::vector<std::string>> &value){std::string object = j.Get<std::string>(key);int i = 1;while ( i < object.length() - 1){std::vector<std::string> item;if (object[i] == '['){std::string item_string;i++;while (object[i] != ']' && object[i] != '['){if (object[i] != ',' && object[i] != '"' && object[i] != ' '){item_string += object[i];}else if (object[i] == ',' || ( object[i] == '"'&& object[i+1] == ']')){item.push_back(item_string);item_string = "";}i++;}}if(!item.empty())value.push_back(item);i++;}}
private:
};
模版函数
template<typename R>
void get_value(tiny::TinyJson j, std::string key, R &value)
{Json::get_value(j, key, value);
}
使用:
//序列化
tiny::TinyJson j = Json::parse(data);
//普通元素
std::string cdk;
get_value(j,std::string("cdk"),cdk);
//list数组元素
tiny::xarray arry;
get_value(j, std::string("frist_reward_goods"), arry);
//vector数组元素
std::vector<std::vector<std::string>> vec;
get_value(j, std::string("frist_reward_goods"), vec);
其他
对TinyJson的再次封装,使使用足够方便。因为本人只使用解析,所以针对修改是针对TinyJson的解析修改。其他还需要其他人完善。
也可以将我上诉的元素再次封装于tinyjson.hpp.获取根据其他的使用再次封装。
想着上传合并到原作者的git分支,但是已经有两年没有更新就没有做。
如需源码请留言。
C++轻量级Json解析工具—TinyJson相关推荐
- json解析工具(json解析工具 python)
常用的xml,json解析工具有哪些 1.定义介绍 (1).XML定义 扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可 ...
- cJSON_译(C中的超轻量级JSON解析器)
cJSON ANSI C中的超轻量级JSON解析器. 通行证 执照 版权所有(c)2009-2017 Dave Gamble和cJSON贡献者 特此免费授予获得此软件和相关文档文件("软件& ...
- 一文吃透Json解析工具类合集(FastJson、Jackson、Gson)
Json解析工具类 前言 一.各个JSON技术的简介 1.1 FastJson角色 1.2 Jackson角色 1.3 Gson角色 二.使用步骤 2.1 引入库 1.FastJson依赖 2.Jac ...
- Json解析工具Jackson(使用注解)
接上一篇文章Json解析工具Jackson(简单应用),jackson在实际应用中给我们提供了一系列注解,提高了开发的灵活性,下面介绍一下最常用的一些注解 @JsonIgnoreProperties ...
- JSON解析工具比较,主要GSON和FastJSON
转自:http://www.cnblogs.com/kunpengit/p/4001680.html 一 .各个JSON技术的简介和优劣 1.json-lib json-lib最开始的也是应用最广泛的 ...
- Java:JSON解析工具-org.json
一.简介 org.json是Java常用的Json解析工具,主要提供JSONObject和JSONArray类,现在就各个类的使用解释如下. 二.准备 1.在使用org.json之前,我们应该先从该网 ...
- 自定义Json解析工具
此博客为博主原创文章,转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10689536.html fastjson是很好用的json解析工具,只可惜项目中要 ...
- Java常用的几种JSON解析工具
一.Gson:Google开源的JSON解析库 1.添加依赖 <!--gson--> <dependency><groupId>com.google.code.gs ...
- FastJson快速上手【Json解析工具】
目录 一.spring boot工程中引入FastJson依赖 二.调用JSON类的静态方法直接进行json序列化和反序列化 2.1 序列化 2.2 反序列化 三.快速演示: 四.思考 五.web案例 ...
- java 自定义json解析注解 复杂json解析 工具类
java 自定义json解析注解 复杂json解析 工具类 目录 java 自定义json解析注解 复杂json解析 工具类 1.背景 2.需求-各式各样的json 一.一星难度json[json对象 ...
最新文章
- python模拟退火(Simulated Annealing)参数寻优实战
- netcore磊科小企路由器使用测试-nr235p--测试结果令人气愤!!!!
- php7嵌入,ngx_php7
- IDEA 2020.3 连接mysql数据库报错解决
- 找不到服务器micro,Go Micro服务发现
- Codeforces Round #518 (Div. 2): D. Array Without Local Maximums(DP)
- atittit.表单验证的实现方式以及原理本质以及选型以及自定义兼容easyui dsl规则的表单验证
- 单片机的C语言应用程序设计实训教程,单片机的c语言程序设计实训
- su灯光插件_V-Ray for SketchUp渲染外部照明快速入门
- 什么样的Python培训机构才是好机构?
- RAITE Hypervisor介绍
- 算法——弗洛伊德算法(Floyd-Warshall)(图论)(c++)
- 如何找回回收站清空的重要文件
- chrome浏览器强制采用https加密链接
- 【转载】API:简单实现多人聊天室
- C语言:浮点型的基本知识
- 非金融机构不良资产市场的规模
- 【Fiori系列】为什么SAP Fiori活的如此精致
- 【牛投客】:牛投客经过三年的投资
- 对可编程控制器的专有协议进行模糊处理找到影响物理控制相关的漏洞
热门文章
- java.awt.Image转 com.lowagie.text.Image
- sh计算机c盘如何管理,c盘瘦身三种方法详解
- 产品经理面试题目转载
- tp6 实现汉字转拼音
- 快速入门学习数字图像处理(冈萨雷斯第三版)
- ucint核心边缘分析_ucinet社会网络分析笔记(一)网络密度、中心度、凝聚子群、核心-边缘...
- TUXEDO中间件介绍及应用
- 数据库系统概论第五版习题解析
- Mac里的airdrop传输文件
- [读书笔记]普林斯顿微积分读本(修订版)-未完工