nlohmannjson学习使用指南

nlohmannjson学习使用指南,第1张

文章目录
  • 一、nlohmann/json
    • 1、简介
    • 2、代码下载
    • 3、代码编译
    • 4. 简单使用
      • 4.1 简单使用
      • 4.2 序列化
      • 文件IO

一、nlohmann/json 1、简介

1、类似python调用json库一样, 非常的方便和直观。 绑定STL。
2、内存占用优化和运行速度并不是非常关心。

那里有无数的JSON库,每个库甚至都有其存在的理由。我们有这些设计目标:

直观的语法。 在 Python 等语言中,JSON 感觉就像是一流的数据类型。我们使用了现代 C++ 的所有运算符魔术来在您的代码中实现相同的感觉。看看下面的例子,你就会明白我的意思。

微不足道的整合。 我们的整个代码由一个头文件组成json.hpp。就是这样。没有库,没有子项目,没有依赖项,没有复杂的构建系统。该类是用 C++11 编写的。总而言之,一切都不需要调整编译器标志或项目设置。

非常全面的测试。 我们的课程经过大量单元测试,涵盖了100%的代码,包括所有异常行为。此外,我们使用Valgrind和Clang Sanitizers检查了没有内存泄漏。Google OSS-Fuzz还针对所有解析器 24/7 运行模糊测试,迄今为止有效执行了数十亿次测试。为了保持高质量,该项目遵循核心基础设施倡议 (CII) 最佳实践。

其他方面对我们来说并不那么重要:

内存效率。 每个 JSON 对象都有一个指针(联合的最大大小)和一个枚举元素(1 个字节)的开销。默认泛化使用以下 C++ 数据类型:std::string字符串、int64_t数字、对象、数组和uint64_t布尔值。但是,您可以根据需要对通用类进行模板化。doublestd::mapstd::vectorboolbasic_json

速度。 当然有更快的 JSON 库。但是,如果您的目标是通过添加带有单个标头的 JSON 支持来加速您的开发,那么这个库就是您要走的路。如果您知道如何使用std::vectoror std::map,那么您已经准备好了。

2、代码下载

nlohmann/json github url

3、代码编译
  1. 下载代码
  2. cmake脚本中使用:set(JSON_BuildTests OFF CACHE INTERNAL "")
  3. 添加下砸代码的相对路径 add_subdirectory(nlohmann_json)
  4. 最后给可执行文件链接库文件target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)

# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")

# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
# set(JSON_Install OFF CACHE INTERNAL "")

# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build.  It's generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
4. 简单使用

json库的使用类似python 中对json的使用,都是有基本的包装

4.1 简单使用
  • 比如要实现下面这个格式的json
{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}
  • 实现方式1

// create an empty structure (null)
json j;

// add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141;

// add a Boolean that is stored as bool
j["happy"] = true;

// add a string that is stored as std::string
j["name"] = "Niels";

// add another null object by passing nullptr
j["nothing"] = nullptr;

// add an object inside the object
j["answer"]["everything"] = 42;

// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };

// add another object (using an initializer list of pairs)
j["object"] = { {"currency", "USD"}, {"value", 42.99} };

  • 实现方式2

// instead, you could also write (which looks very similar to the JSON above)
json j2 = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"answer", {
    {"everything", 42}
  }},
  {"list", {1, 0, 2}},
  {"object", {
    {"currency", "USD"},
    {"value", 42.99}
  }}
};

不需要告诉编译器,json数值的类型,会有自动类型判断,当然,如果读者想要声明变量类型的话

可以参考json::array() and json::object()

// a way to express the empty array []
json empty_array_explicit = json::array();

// ways to express the empty object {}
json empty_object_implicit = json({});
json empty_object_explicit = json::object();

// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
4.2 序列化
  • 反序列化

可以通过在字符串尾部追加 _json 来将 string 类型的字面值进行转化:

// create object from string literal
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;

// or even nicer with a raw string literal
auto j2 = R"(
  {
    "happy": true,
    "pi": 3.141
  }
)"_json;

如果不添加`_json`, 传递的string类型的数值不会被转化为。

当然,也可以直接显式的进行
```c++
// parse explicitly
auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");
  • 序列化
    将json格式的对象转化为string类型的字符串:
// explicit conversion to string
std::string s = j.dump();    // {"happy":true,"pi":3.141}

// serialization with pretty printing
// pass in the amount of spaces to indent
std::cout << j.dump(4) << std::endl;
// {
//     "happy": true,
//     "pi": 3.141
// }
文件IO
  • 文件I O

// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;

// write prettified JSON to another file
std::ofstream o("pretty.json");
o << std::setw(4) << j << std::endl;
  • 输入输出IO
// deserialize from standard input
json j;
std::cin >> j;

// serialize to standard output
std::cout << j;

// the setw manipulator was overloaded to set the indentation for pretty printing
std::cout << std::setw(4) << j << std::endl;
  • 从迭代器中读取
std::vector v = {'t', 'r', 'u', 'e'};
json j = json::parse(v.begin(), v.end());

  • STL 格式的数据导入模式
// create an array using push_back
json j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);

// also use emplace_back
j.emplace_back(1.78);

// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it) {
  std::cout << *it << '\n';
}

// range-based for
for (auto& element : j) {
  std::cout << element << '\n';
}

// getter/setter
const auto tmp = j[0].get();
j[1] = 42;
bool foo = j.at(2);

// comparison
j == R"(["foo", 1, true, 1.78])"_json;  // true

// other stuff
j.size();     // 4 entries
j.empty();    // false
j.type();     // json::value_t::array
j.clear();    // the array is empty again

// convenience type checkers
j.is_null();
j.is_boolean();
j.is_number();
j.is_object();
j.is_array();
j.is_string();

// create an object
json o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;

// also use emplace
o.emplace("weather", "sunny");

// special iterator member functions for objects
for (json::iterator it = o.begin(); it != o.end(); ++it) {
  std::cout << it.key() << " : " << it.value() << "\n";
}

// the same code as range for
for (auto& el : o.items()) {
  std::cout << el.key() << " : " << el.value() << "\n";
}

// even easier with structured bindings (C++17)
for (auto& [key, value] : o.items()) {
  std::cout << key << " : " << value << "\n";
}

// find an entry
if (o.contains("foo")) {
  // there is an entry with key "foo"
}

// or via find and an iterator
if (o.find("foo") != o.end()) {
  // there is an entry with key "foo"
}

// or simpler using count()
int foo_present = o.count("foo"); // 1
int fob_present = o.count("fob"); // 0

// delete an entry
o.erase("foo");

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/915140.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-16
下一篇2022-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存