话不多说,先上code!
1 2 3 4 5 6 7 8 9 10
| json obj = { { "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++ 量身打造的轻量级 JSON 通用工具,轻松完成 JSON 解析和序列化功能,并和 C++ 输入输出流交互。
Nomango/jsonxx
使用介绍
1 2
| #include "jsonxx/json.hpp" using namespace jsonxx;
|
使用 operator[]
为 JSON 对象赋值
1 2 3 4 5 6 7
| json j; 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 对象赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| json arr = { 1, 2, 3 };
json obj = { { "user", { { "id", 10 }, { "name", "Nomango" } } } };
json obj2 = { { "nul", nullptr }, { "number", 1 }, { "float", 1.3 }, { "boolean", false }, { "string", "中文测试" }, { "array", { 1, 2, true, 1.4 } }, { "object", { "key", "value" } } };
|
使用辅助方法构造数组或对象
1 2
| json arr = json::array({ 1 }); json obj = json::object({ "user", { { "id", 1 }, { "name", "Nomango" } } });
|
1 2 3 4 5 6 7
| bool is_null(); bool is_boolean(); bool is_integer(); bool is_float(); bool is_array(); bool is_object();
|
1 2 3 4 5 6
| auto b = j["boolean"].as_boolean(); auto i = j["number"].as_integer(); auto f = j["float"].as_float(); const auto& arr = j["array"].as_array(); const auto& obj = j["user"].as_object();
|
1 2 3 4 5 6
| bool b = j["boolean"]; int i = j["number"]; double d = j["float"]; std::vector<json> arr = j["array"]; std::map<std::string, json> obj = j["user"];
|
若 JSON 值类型与待转换类型不相同也不协变,会引发 json_type_error 异常
1 2
| int n; bool ret = j["boolean"].get_value(&n);
|
1 2 3 4
| for (auto& j : obj) { std::cout << j << std::endl; }
|
1 2 3 4
| for (auto iter = obj.begin(); iter != obj.end(); iter++) { std::cout << iter.key() << ":" << iter.value() << std::endl; }
|
1 2
| json j = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
|
1 2 3 4 5
| std::ifstream ifs("sample.json");
json j; ifs >> j;
|
1 2 3 4
| std::string json_str = j.dump();
std::string pretty_str = j.dump(4, ' ');
|
1 2 3
| std::ofstream ofs("output.json"); ofs << j << std::endl;
|
1 2 3
| std::ofstream ofs("pretty.json"); ofs << std::setw(4) << j << std::endl;
|
1 2 3
| json j; std::cout << j;
|
更多
若你需要将 JSON 解析和序列化应用到非 std::basic_stream 流中,可以通过创建自定义 output_adapter
和 input_adapter
的方式实现。
实际上 json::parse() 和 json::dump() 函数也是通过自定义的 string_output_adapter
和 string_input_adapter
实现对字符串内容的输入和输出。
详细内容请参考 json_parser.hpp 和 json_serializer.hpp