C++json库——nlohmann-json

文章介绍了nlohmann/json库,一个轻量级的C++JSON处理库,展示了如何创建、操作JSON对象、数组,以及从文件和字符串转换JSON,包括使用stl容器和指定键值对的顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

nlohmann/json

nlohmann/json是一个使用现代c++编写的一个json库,该库是head-only的。

json介绍

关于json的介绍可以参考:CJSON简单介绍

使用

直接包含

single_include/
└── nlohmann
    ├── json_fwd.hpp
    └── json.hpp

一般只要包含json.hpp,如果需要forward-declarations那么可以包含json_fwd.hpp。

注意,因为库使用了c++11特性,所以在编译的时候需要用C++11以上的标准编译。

#include <iostream>
#include "include/single_include/nlohmann/json.hpp"

using json = nlohmann::json;

int main()
{
    // create the different JSON values with default values
    json j_null(json::value_t::null);
    json j_boolean(json::value_t::boolean);
    json j_number_integer(json::value_t::number_integer);
    json j_number_float(json::value_t::number_float);
    json j_object(json::value_t::object);
    json j_array(json::value_t::array);
    json j_string(json::value_t::string);

    // serialize the JSON values
    std::cout << j_null << '\n';
    std::cout << j_boolean << '\n';
    std::cout << j_number_integer << '\n';
    std::cout << j_number_float << '\n';
    std::cout << j_object << '\n';
    std::cout << j_array << '\n';
    std::cout << j_string << '\n';
}

运行结果:

$./a.out 
null
false
0
0.0
{}
[]
""

例子

从文件中导入json对象

#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

// ...

std::ifstream f("example.json");
json data = json::parse(f);

使用json字面量创建json对象

// Using (raw) string literals and json::parse
json ex1 = json::parse(R"(
  {
    "pi": 3.141,
    "happy": true
  }
)");

// Using user-defined (raw) string literals
using namespace nlohmann::literals;
json ex2 = R"(
  {
    "pi": 3.141,
    "happy": true
  }
)"_json;

// Using initializer lists
json ex3 = {
  {"happy", true},
  {"pi", 3.141},
};

直接创建并操作json对象

// 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} };

// 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 array

  // 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}});

  std::cout << empty_array_explicit << '\n';
  std::cout << empty_object_implicit << '\n';
  std::cout << empty_object_explicit << '\n';
  std::cout << array_not_object << '\n';

json对象转string

  json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
  // 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;

  json j_string = "this is a string";

  // retrieve the string value
  auto cpp_string = j_string.template get<std::string>();
  // retrieve the string value (alternative when a variable already exists)
  std::string cpp_string2;
  j_string.get_to(cpp_string2);

  // retrieve the serialized value (explicit JSON serialization)
  std::string serialized_string = j_string.dump();

  // output of original string
  std::cout << cpp_string << " == " << cpp_string2
            << " == " << j_string.template get<std::string>() << '\n';
  // output of serialized value
  std::cout << j_string << " == " << serialized_string << std::endl;

  // write prettified JSON to another file
  std::ofstream o("pretty.json");
  o << std::setw(4) << j << std::endl;

string转json对象

  // 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;
  // parse explicitly
  auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");
  // store a string in a JSON value
  json j_string = "this is a string";

  std::cout << j3 << '\n';
  std::cout << j_string << '\n';

  // deserialize from standard input
  json j_i;
  std::cin >> j_i;

  std::cout << j_i << '\n';
  // the setw manipulator was overloaded to set the indentation for pretty
  // printing
  std::cout << std::setw(4) << j_i << std::endl;

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

  std::cout << j_s << '\n';

  std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
  json j_v = json::parse(v.begin(), v.end());
  json j_v1 = json::parse(v);
  std::cout << j_v << '\n';
  std::cout << j_v1 << '\n';

像stl容器一样使用json

  // create an array using push_back
  json j;
  j.push_back("foo");
  j.push_back(1);
  j.push_back(true);

  std::cout << j << '\n';

  // also use emplace_back
  j.emplace_back(1.78);
  std::cout << j << '\n';
  // 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].template get<std::string>();
  j[1] = 42;
  bool foo = j.at(2);

  // comparison
  std::cout << (j == R"(["foo", 1, true, 1.78])"_json) << '\n'; // true

  // other stuff
  std::cout << j.size() << '\n';                // 4 entries
  j.empty();                                    // false
  std::cout << typeid(j.type()).name() << '\n'; // json::value_t::array
  j.clear();                                    // the array is empty again

  // convenience type checkers
  std::cout << j.is_null() << '\n';
  std::cout << j.is_boolean() << '\n';
  std::cout << j.is_number() << '\n';
  std::cout << j.is_object() << '\n';
  std::cout << j.is_array() << '\n';
  std::cout << j.is_string() << '\n';

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

  std::cout << o << '\n';

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

  std::cout << o << '\n';

  // 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")) {
    std::cout << R"(there is an entry with key "foo")" << '\n';
  }

  // or via find and an iterator
  if (o.find("foo") != o.end()) {
    std::cout << R"(there is an entry with key "foo")" << '\n';
  }

  // or simpler using count()
  int foo_present = o.count("foo"); // 1
  int fob_present = o.count("fob"); // 0
  std::cout << foo_present << '\n';
  std::cout << fob_present << '\n';

  // delete an entry
  o.erase("foo");
  std::cout << o << '\n';

stl容器转json array

  std::vector<int> c_vector{1, 2, 3, 4};
  json j_vec(c_vector);
  std::cout << j_vec << '\n';

  std::deque<double> c_deque{1.2, 2.3, 3.4, 5.6};
  json j_deque(c_deque);
  std::cout << j_deque << '\n';

  std::list<bool> c_list{true, true, false, true};
  json j_list(c_list);
  std::cout << j_list << '\n';

  std::forward_list<int64_t> c_flist{12345678909876, 23456789098765,
                                     34567890987654, 45678909876543};
  json j_flist(c_flist);
  std::cout << j_list << '\n';

  std::array<unsigned long, 4> c_array{{1, 2, 3, 4}};
  json j_array(c_array);
  std::cout << j_array << '\n';

  std::set<std::string> c_set{"one", "two", "three", "four", "one"};
  json j_set(c_set); // only one entry for "one" is used
  std::cout << j_set << '\n';

  std::unordered_set<std::string> c_uset{"one", "two", "three", "four", "one"};
  json j_uset(c_uset); // only one entry for "one" is used
  std::cout << j_uset << '\n';

  std::multiset<std::string> c_mset{"one", "two", "one", "four"};
  json j_mset(c_mset); // both entries for "one" are used
  std::cout << j_mset << '\n';

  std::unordered_multiset<std::string> c_umset{"one", "two", "one", "four"};
  json j_umset(c_umset); // both entries for "one" are used
  std::cout << j_umset << '\n';

stl容器转json object

  std::map<std::string, int> c_map{{"one", 1}, {"two", 2}, {"three", 3}};
  json j_map(c_map);
  std::cout << j_map << '\n';

  std::unordered_map<const char *, double> c_umap{
      {"one", 1.2}, {"two", 2.3}, {"three", 3.4}};
  json j_umap(c_umap);
  std::cout << j_umap << '\n';

  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
  std::cout << j_mmap << '\n';

  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
  std::cout << j_ummap << '\n';

限制

字符集

只支持UTF-8作为输入

注释

不支持json注释

key的顺序

默认不保存json中key的顺序,即打印的key的顺序是随机的。如果要支持,使用nlohmann::ordered_json试试。

参考

https://json.nlohmann.me/
https://github.com/miloyip/nativejson-benchmark

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值