json for modern c++的使用
来源:互联网 发布:购物类网站数据库设计 编辑:程序博客网 时间:2024/06/03 13:16
最近学习了json for modern c++的使用,在此总结一些常用功能使用方法。
老规矩,还是先简单介绍一下什么是json吧。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
今天介绍的json版本是在c++下使用的,是一个开源项目。
GitHub开源项的地址:https://github.com/nlohmann/json
json for modern c++是一个德国大牛nlohmann写的,该版本的json有以下特点:
1.直观的语法。
2.整个代码由一个头文件组成json.hpp,没有子项目,没有依赖关系,没有复杂的构建系统,使用起来非常方便。
3.使用c++11标准编写。
4.使用json 像使用STL容器一样。
5.STL和json容器之间可以相互转换。
…
如何使用?
将github上的src文件夹里的json.hpp头文件下载保存到当前目录中。
在代码中包含json.hpp头文件并引入json作用域
#include "json.hpp"using json = nlohmann::json;
常用功能:
一.创建json对象
1.使用cin,cout输入输出流。
json提供了cin,cout的输入输出流的操作符。但需要注意的是,cin要有ctr + D结束输入。cin会把从标准输入的内容反序列化,cout会自动把json序列化,以string形式输出。
#include<iostream>#include"json.hpp"using namespace std;using json=nlohmann::json;int main(){ json j; //创建json类 cin>>j; //从cin读入json对象 cout<<j; //输出序列化的json return 0;}/*输入:{ "pi": 3.141, "happy": true, "name": "Niels", "nothing": null, "answer": { "everything": 42 }, "list": [1, 0, 2], "object": { "currency": "USD", "value": 42.99 }}输出:{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency":"USD","value":42.99},"pi":3.141}*/
2.提供根据键直接生成键值对的方法。(类似于map,如果不存在该键的话,就生成一个这个键。)
#include <iostream>#include "json.hpp"using json = nlohmann::json;using namespace std;int main() { // 创建一个json对象(null) json j; //添加一个存储为double的数字 j["pi"] = 3.141; // 添加一个布尔值 j["happy"] = true; // 添加一个存储为std :: string的字符串 j["name"] = "Niels"; // 通过传递nullptr添加另一个空对象 j["nothing"] = nullptr; // 在对象中添加对象 j["answer"]["everything"] = 42; //添加一个数组,其存储为std::vector(使用初始化列表) j["list"] = { 1, 0, 2 }; // 在一个对象中添加另一个对象 j["object"] = { {"currency", "USD"}, {"value", 42.99} }; // 也可以通过直接赋值方式创建json对象,两种方式创建结果相同 json j2 = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothing", nullptr}, {"answer", { {"everything", 42} }}, {"list", {1, 0, 2}}, {"object", { {"currency", "USD"}, {"value", 42.99} }} }; cout << j << endl; cout << endl; cout << j2 << endl; return 0;}/*输出:{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency":"USD","value":42.99},"pi":3.141}{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency":"USD","value":42.99},"pi":3.141}*/
3.在所有上述情况下,你不需要“告诉”编译器要使用哪个JSON值。如果你想明确或表达一些边缘的情况下,可以使用json::array,json::object。
#include <iostream>#include "json.hpp"using json = nlohmann::json;using namespace std;int main() { //创建一个空数组 json empty_array_explicit = json::array(); // 创建一个空对象的两种方式 json empty_object_implicit = json({}); json empty_object_explicit = json::object();}
4.几点注意
1).array是一个数组,可以用数字直接下标访问。
json array = { "a",6,"xin",8 };cout << array[0] << endl;
2).数组中包含一个数组
json array = { {"a",6}, "xin",8 };cout << array[0][0] << endl; //输出数组里的数组元素中的第一个元素的值
3).数组中包含一个对象
json array = { {{"a",6}}, "xin",8 };//输出数组中第一个元素"a"对应的键值cout << array[0]["a"] << endl;
4).对象中嵌套一个对象和一个数组
json object = { {"a",{{"feng",6}}},{"b",{1,2,3}} }; cout << object << endl;/*输出:{"a":{"feng":6},"b":[1,2,3]}*/
二.序列化
将json对象序列化,成为字符串
1.标准输出自动序列化
json jstd :: cout << j;// setw操纵器被重载以设置漂亮打印的缩进 std :: cout << std :: setw( 4)<< j << std :: endl;
2.使用dump()函数
//显式转换为string std::string s = j.dump(); // {\"happy\":true,\"pi\":3.141}//序列化与漂亮的打印//传入空格的数量缩进 std::cout << j.dump(4) << std::endl;// 输出://{// "happy": true,// "pi": 3.141// }
三.反序列化
将数据流转化为json对象
1.从标准输入反序列化
json jstd :: cin >> j;
2.通过附加_json到字符串文字来创建对象(反序列化):
//从字符串文字创建对象 json j = " { \" happy \":true,\" pi \":3.141} " _json;//或者原始字符串文字auto j2 = R"( { "happy":true, "pi":3.141 } )" _json;
请注意,没有附加_json后缀,传递的字符串文字不会被解析,而只是用作JSON字符串值。也就是说,json j = "{ \"happy\": true, \"pi\": 3.141 }"
只存储字符串"{ "happy": true, "pi": 3.141 }"
而不是解析实际的对象。
3.使用json::parse()函数
//明确解析auto j3 = json::parse(" { \" happy \":true,\" pi \":3.141} ");
4.从迭代器范围读取
您还可以从迭代器范围读取JSON; 也就是说,可以从其内容存储为连续字节序列的迭代器访问的任何容器,例如std::vector
std :: vector < uint8_t > v = { ' t ',' r ',' u ',' e ' };json j = json :: parse(v.begin(),v.end());//或std :: vector < uint8_t > v = { ' t ',' r ',' u ',' e ' };json j = json :: parse(v);
四.与STL适应
nlohmann设计的JSON类,就像一个STL容器一样。其实它满足了可逆容器要求。
//使用push_back创建一个数组json j;j.push_back("foo");j.push_back(1);j.push_back(true);// 也可以使用emplace_back j.emplace_back(1.78);// 使用迭代器访问for (json::iterator it = j.begin(); it != j.end(); ++it) { std::cout << *it << '\n';}// 基于范围for循环for (auto& element : j) { std::cout << element << '\n';}// 赋值操作const std::string tmp = j[0];j[1] = 42;bool foo = j.at(2);// 比较操作j == "[\"foo\", 1, true]"_json; // true// 其他函数j.size(); // 3 j.empty(); // falsej.type(); // json::value_t::arrayj.clear(); // 使数组再次为空// 方便类型检查j.is_null();j.is_boolean();j.is_number();j.is_object();j.is_array();j.is_string();// 创建一个数组json o;o["foo"] = 23;o["bar"] = false;o["baz"] = 3.141;// 也可以使用emplaceo.emplace("weather", "sunny");// 使用迭代器输出for (json::iterator it = o.begin(); it != o.end(); ++it) { std::cout << it.key() << " : " << it.value() << "\n";}// 使用find函数if (o.find("foo") != o.end()) { // there is an entry with key "foo"}// count函数int foo_present = o.count("foo"); // 1int fob_present = o.count("fob"); // 0// 删除条目 o.erase("foo");
五.从STL容器转换
任何序列容器(std::array,std::vector,std::deque,std::forward_list,std::list),其值可以被用于构建JSON类型(例如,整数,浮点数,布尔值,字符串类型,或者再次在本节中描述STL容器)可被用于创建JSON阵列。这同样适用于类似的关联容器(std::set,std::multiset,std::unordered_set,std::unordered_multiset),但是在这些情况下,阵列的元素的顺序取决于元素是如何在各个STL容器排序。
std::vector<int> c_vector {1, 2, 3, 4};json j_vec(c_vector);// [1, 2, 3, 4]std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};json j_deque(c_deque);// [1.2, 2.3, 3.4, 5.6]std::list<bool> c_list {true, true, false, true};json j_list(c_list);// [true, true, false, true]std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};json j_flist(c_flist);// [12345678909876, 23456789098765, 34567890987654, 45678909876543]std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};json j_array(c_array);// [1, 2, 3, 4]std::set<std::string> c_set {"one", "two", "three", "four", "one"};json j_set(c_set); // only one entry for "one" is used// ["four", "one", "three", "two"]std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};json j_uset(c_uset); // only one entry for "one" is used// maybe ["two", "three", "four", "one"]std::multiset<std::string> c_mset {"one", "two", "one", "four"};json j_mset(c_mset); // both entries for "one" are used// maybe ["one", "two", "one", "four"]std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};json j_umset(c_umset); // both entries for "one" are used// maybe ["one", "two", "one", "four"]
同样,任何键值容器(std::map,std::multimap,std::unordered_map,std::unordered_multimap),其键可以构造一个std::string,并且其值可以被用于构建JSON类型(参见上文实施例)可用于创建一个JSON对象。请注意,在多重映射的情况下,JSON对象中仅使用一个键,该值取决于STL容器的内部顺序。
<br>std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };json j_map(c_map);// {"one": 1, "three": 3, "two": 2 }std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} };json j_umap(c_umap);// {"one": 1.2, "two": 2.3, "three": 3.4}std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };json j_mmap(c_mmap); // only one entry for key "three" is used// maybe {"one": true, "two": true, "three": true}std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };json j_ummap(c_ummap); // only one entry for key "three" is used// maybe {"one": true, "two": true, "three": true}
六.隐式转换
JSON对象的类型由要存储的表达式自动确定。同样,存储的值被隐式转换。
<br>// strings std :: string s1 = “ Hello,world!” ;json js = s1;std :: string s2 = js;// Booleans bool b1 = true ;json jb = b1;bool b2 = jb;// numbers int i = 42 ;json jn = i;double f = jn;//...
还可以明确要求该值:
std :: string vs = js.get <std :: string>();bool vb = jb.get < bool >();int vi = jn.get < int >();//...
七.任意类型转换
每个类型都可以以JSON序列化,而不仅仅是STL容器和标量类型。通常情况下,你会做这些事情:
namespace ns { struct person { std::string name; std::string address; int age; };}ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};// 转换为JSON:将每个值复制到JSON对象中json j;j["name"] = p.name;j["address"] = p.address;j["age"] = p.age;// ...// 从JSON转换:从JSON对象复制每个值ns::person p { j["name"].get<std::string>(), j["address"].get<std::string>(), j["age"].get<int>()};
或者,使用一种更简便的用法
// 创建一个person类并初始化ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60};// 隐式转换: person -> jsonjson j = p;std::cout << j << std::endl;// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}// 隐式转换: json -> personns::person p2 = j;// 测试是否完全相同assert(p == p2);
以上是对json for modern c++基本功能的使用总结,如有哪里有误,欢迎指出,相互学习交流。
- json for modern c++的使用
- JSON for Modern C++
- Modern UI for WPF的使用
- JSON for Modern C++ 玩具
- Modern C++(二)Range-based for loop(基于范围的for循环)
- 基于modern ui for wpf的在线公开课平台 之三 使用grid布局
- Support For C++11/14/17 Features (Modern C++)
- 基于modern ui for wpf的在线公开课平台 之五 使用ListBox实现图片列表效果
- JSON C库的使用
- C++json文件的使用
- c语言json的使用
- Modern Objective-C
- Modern Objective-C
- Modern Objective-C
- Adopting Modern Objective-C
- Adopting Modern Objective-C
- Adopting Modern Objective-C
- 《Effective Modern C++》读书笔记
- 『 推荐算法』笔记一:什么是推荐系统
- 配置Tengine服务器
- ramdisk.img文件解析
- 程序员,这12个问题让经理比你痛苦多了
- WordPress新主题Tint Pro(Tinection重构版)无域名限制主题[更新至2.0.6]
- json for modern c++的使用
- HDOJ--2163 Palindromes
- 面试21之检查一颗二叉树是否为二叉查找树
- PAT-A-1081. Rational Sum (20)
- Apache2.4.23本地访问正常但局域网无法访问 httpd.conf设置
- hdu 5703 Desert
- JMeter学习笔记3-如何创建第一个JMeter测试用例
- 反射机制 有什么用
- 4412驱动-key 按键驱动