话不多说,先上code!
// 最简单的方式创建一个json对象jsonobj={{"null",nullptr},{"number",1},{"float",1.3},{"boolean",false},{"string","中文测试"},{"array",{1,2,true,1.4}},{"object",{"key","value"}}};
有没有觉得单看这段代码都有种js内味了(误)。但是没错,上面这段代码是C++
!
如果这引起了你的些许兴趣,那就说明这个轮子成功了。
故事在前
造轮子的初衷是在两年前,我记得那天空中都是圆圆的轮状云,突然想给自己的游戏做一个json格式的配置文件。当我百度一下C++ json库时,被一张图震惊了
当然震惊我的不是这些库的性能,而是竟然足足有28个比较火的库在互相对比。。还有哪个语言可以做到让这么多人乐此不疲的为了一个小功能写那些重复的逻辑和代码呢?
然后我选了几个比较热门的库看看usage,看的越多,震惊越多。
每一个库的接口设计都无法获得我在审美上的认同,甚至有些demo代码又长又臭,这时候真的是想感叹一句:我爱Golang!(误)
于是那天的云彩显得越发的圆润。直到那天我才知道,原来C++的设计美学从底子里就是圆形的。
所以各位手下留情,这个库的存在并不是提升了多少性能,或者支持了多少json标准,而仅仅是为了美才诞生的。
这个库的slogan也很简单:
愿天堂没有C++
好了,认真介绍一下这个库:
JSONXX
一个为 C++11 量身打造的轻量级 JSON 通用工具,轻松完成 JSON 解析和序列化功能,并和 C++ 输入输出流交互。
使用介绍
- 引入 jsonxx 头文件
include"jsonxx/json.hpp"usingnamespacejsonxx;
- 使用 C++ 的方式的创建 JSON 对象
使用operator[]
为 JSON 对象赋值
jsonj;j["number"]=1;j["float"]=1.5;j["string"]="this is a string";j["boolean"]=true;j["user"]["id"]=10;j["user"]["name"]="Nomango";
使用std::initializer_list
为 JSON 对象赋值
// 使用初始化列表构造数组jsonarr={1,2,3};// 使用初始化列表构造对象jsonobj={{"user",{{"id",10},{"name","Nomango"}}}};// 第二个对象jsonobj2={{"nul",nullptr},{"number",1},{"float",1.3},{"boolean",false},{"string","中文测试"},{"array",{1,2,true,1.4}},{"object",{"key","value"}}};
使用辅助方法构造数组或对象
jsonarr=json::array({1});jsonobj=json::object({"user",{{"id",1},{"name","Nomango"}}});
- 判断 JSON 对象的值类型
// 判断 JSON 值类型boolis_null();boolis_boolean();boolis_integer();boolis_float();boolis_array();boolis_object();
- JSON 对象的类型转换
// 显示转换autob=j["boolean"].as_boolean();// boolautoi=j["number"].as_integer();// int32_tautof=j["float"].as_float();// floatconstauto&arr=j["array"].as_array();// arr 实际是 std::vector 类型 constauto&obj=j["user"].as_object();// obj 实际是 std::map 类型 // 强制类型转换boolb=(bool)j["boolean"];inti=(int)j["number"];floatd=(float)j["float"];
若 JSON 值类型与待转换类型不相同也不协变,会引发 json_type_error 异常
- JSON 对象的比较操作符
j["boolean"]==truej["number"]==1j["number"]!=2j["number"]>0j["float"]<3
- 取值的同时判断类型
intn;boolret=j["boolean"].get_value(&n);// 若取值成功,ret 为 true
- JSON 对象类型和数组类型的遍历
// 使用迭代器遍历for(autoiter=obj.begin();iter!=obj.end();iter++){std::cout<<iter.key()<<":"<<iter.value()<<std::endl;}
- JSON 解析
// 解析字符串jsonj=json::parse("{\"happy\": true,\"pi\": 3.141 }");// 从文件读取 JSONstd::ifstreamifs("sample.json");jsonj;ifs>>j;// 从标准输入流读取 JSONjsonj;std::cin>>j;
- JSON 序列化
// 序列化为字符串std::stringjson_str=j.dump();// 美化输出,使用 4 个空格对输出进行格式化std::stringpretty_str=j.dump(4,);// 将 JSON 内容输出到文件std::ofstreamofs("output.json");ofs<<j<<std::endl;// 将 JSON 内容输出到文件,并美化std::ofstreamofs("pretty.json");ofs<<std::setw(4)<<j<<std::endl;// 将 JSON 内容输出到标准输出流jsonj;std::cout<<j;// 可以使用 std::setw(4) 对输出内容美化
- JSON 与任意类型的转换
通过特化实现 json_bind 类,可以非侵入式的实现任意对象与 JSON 的转换。使用效果:
// 特化实现 json_bind 后,即可方便地将 MyClass 对象和 json 进行互相转换 jsonj;MyClassobj;// 将 MyClass 转换为 jsonjsonxx::to_json(j,obj);// 将 json 转换为 MyClassjsonxx::from_json(j,obj);
特化实现 json_bind 的例子:
// 自定义的角色类classRole{public:Role()=default;Role(conststd::string&name,intage):name_(name),age_(age){}private:friendjson_bind<Role>;// 声明 json_bind 友元std::stringname_;intage_=0;};// 特化实现 json_bind// 需要实现 to_json 和 from_json 两个成员函数template<>classjson_bind<Role>{public:// 将 Role 转换为 jsonvoidto_json(json&j,constRole&v){j["name"]=v.name_;j["age"]=v.age_;}// 将 json 转换为 Rolevoidfrom_json(Role&v,constjson&j){v.name_=j["name"].as_string();v.age_=(int)j["age"];}};
- 任意类型的序列化与反序列化
使用 json_wrap 函数可以让任意类型实现序列化与反序列化,并与输入输出流交互
std::stringstreams;// 把 obj 序列化,并输入到 s 流中s<<json_wrap(obj);// 从 s 流中读取,并把 obj 反序列化s>>json_wrap(obj);
更多
若你需要将 JSON 解析和序列化应用到非 std::basic_stream 流中,可以通过创建自定义output_adapter
和input_adapter
的方式实现。
实际上 json::parse() 和 json::dump() 函数也是通过自定义的string_output_adapter
和string_input_adapter
实现对字符串内容的输入和输出。
详细内容请参考 json_parser.hpp 和 json_serializer.hpp。
写在最后
很多朋友提到这个库的风格和nlohmann/json很像,确实是的,当初看到这个库的时候我感叹一句果然你能想到的别人都实现过了,然后顺手借鉴了一些功能补充进来(误)
所以我也很推荐这个库,nlohmann也许是JSON for modern C++ 的最佳实践了吧!
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容