Skip to content

Instantly share code, notes, and snippets.

@yohm
Created March 7, 2020 06:47
Show Gist options
  • Save yohm/27d69509403b593778b2564e61bbc871 to your computer and use it in GitHub Desktop.
Save yohm/27d69509403b593778b2564e61bbc871 to your computer and use it in GitHub Desktop.
basic usage of nlohmann-json
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
// for convenience
using json = nlohmann::json;
namespace ns {
// a simple struct to model a person
struct person {
std::string name;
std::string address;
int age;
};
void to_json(json& j, const person& p) {
j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
}
void from_json(const json& j, person& p) {
j.at("name").get_to(p.name); // get_to(T& arg) は arg = get<T>() と同じ
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
}
}
int main(int argc, const char* argv[]) {
{
json j;
j["pi"] = 3.141;
j["happy"] = true;
j["name"] = "Niels";
j["nothing"] = nullptr;
j["answer"]["everything"] = 42; // 存在しないキーを指定するとobjectが構築される
j["list"] = { 1, 0, 2 }; // [1,0,2]
j["object"] = { {"currency", "USD"}, {"value", 42.99} }; // {"currentcy": "USD", "value": 42.99}
std::cout << j << std::endl;
json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}
},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}
}
};
std::cout << j2 << std::endl;
json empty_list = json::array(); // []
json empty_obj = json::object(); // {}
std::cout << empty_list << std::endl << empty_obj << std::endl;
}
{
json j = R"({ "happy": true, "pi": 3.141 })"_json;
std::cout << j << std::endl;
}
{
std::string s = R"({ "happy": true, "pi": 3.141 } )";
json j = json::parse(s);
std::cout << j << std::endl;
std::cout << j.dump(4) << std::endl;
}
{
std::ifstream fin("file.json");
json j;
fin >> j;
std::ofstream fout("pretty.json");
fout << std::setw(4) << j << std::endl;
}
{
json j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);
j.emplace_back(1.78); // push_backもemplace_backも使える
// j = ["foo", 1, true, 1.78]
std::cout << j << std::endl;
// iteratorでループを回すこともできる
for (json::iterator it = j.begin(); it != j.end(); ++it) {
std::cout << *it << '\n';
}
// range-based for も使える
for (const json& element : j) {
std::cout << element << '\n';
}
// getter/setter
const auto tmp = j[0].get<std::string>(); // operator[] で要素を取り出す時には型を指定して変換する必要がある
j[1] = 42;
bool foo = j.at(2);
// const auto i = j[0].get<int>(); // operator[] で要素を取り出す時には型を指定して変換する必要がある
if( j == "[\"foo\", 42, true, 1.78]"_json ) {
std::cout << "two jsons are equal" << std::endl;
}
else {
std::cout << "not equal" << std::endl;
}
// other stuff
std::cout << j.size() << ' ' << j.empty() << std::endl;
j.clear();
std::cout << j << std::endl;
}
{
json j = R"( ["foo", 1, true, null, []] )"_json;
for(const json& x: j) {
std::string type;
if( x.is_null() ) { type = "null"; }
else if( x.is_boolean() ) { type = "boolean"; }
else if( x.is_number() ) { type = "number"; }
else if( x.is_object() ) { type = "object"; }
else if( x.is_array() ) { type = "array"; }
else if( x.is_string() ) { type = "string"; }
std::cout << type << std::endl;
const auto t = x.type();
switch(t) {
case json::value_t::null:
type = "null";
break;
case json::value_t::boolean:
type = "boolean";
break;
case json::value_t::number_integer:
type = "integer";
break;
case json::value_t::number_unsigned:
type = "unsigned";
break;
case json::value_t::number_float:
type = "float";
break;
case json::value_t::object:
type = "object";
break;
case json::value_t::array:
type = "array";
break;
case json::value_t::string:
type = "string";
break;
default:
type = "other";
}
std::cout << type << std::endl;
}
}
{
// 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";
}
// find an entry
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");
}
{
std::vector<int> c_vector {1, 2, 3, 4};
json j_vec(c_vector);
std::cout << j_vec << std::endl;
// [1, 2, 3, 4]
}
{
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
json j_map(c_map);
std::cout << j_map << std::endl;
// {"one": 1, "three": 3, "two": 2 }
}
{
std::string s1 = "Hello, world!";
json js = s1;
auto s2 = js.get<std::string>();
std::cout << js << std::endl << s2 << std::endl;
}
{
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
json j = p;
std::cout << j << std::endl;
ns::person p2 = j.get<ns::person>();
std::cout << p2.name << std::endl;
}
{
json j = R"({"foo": 1, "bar": "hello", "baz": true} )"_json;
std::vector<std::uint8_t> v_msgpack = json::to_msgpack(j);
json j2 = json::from_msgpack(v_msgpack);
std::cout << j2 << std::endl; // == {"foo": 1, "bar": "hello", "baz": true}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment