I am using the nlohmann JSON C library to read a JSON file with this structure:
{
"Main": [
{
"obj1": "bar"
},
{
"obj2": "foo"
}
]
}
The main object with key known to the user "Main"
contains an array of objects with unknown key names.
I want to transfer the JSON object in the following program to a C structure. How could this be done?
#include <nlohmann/json.hpp>
#include <iostream>
#include <fstream>
using json = nlohmann::json;
int main()
{
std::ifstream ifs("../test/test_2.json");
json js = json::parse(ifs);
for (json::iterator it = js.begin(); it != js.end(); it)
{
std::cout << it.key() << " :\n";
std::cout << it.value() << "\n";
}
if (js.contains("Main"))
{
json a = js["Main"];
for (size_t idx = 0; idx < a.size(); idx)
{
json o = a.at(idx);
std::cout << o << "\n";
}
}
return 0;
}
Output:
Main :
[{"obj1":"bar"},{"obj2":"foo"}]
{"obj1":"bar"}
{"obj2":"foo"}
CodePudding user response:
You could parse the vector of maps under Main
with:
auto objects{ j.at("Main").get<objects_t>() };
Where:
using object_t = std::map<std::string, std::string>;
using objects_t = std::vector<object_t>;
#include <fmt/ranges.h>
#include <iostream> // cout
#include <map>
#include <nlohmann/json.hpp>
#include <string>
#include <vector>
using json = nlohmann::json;
using object_t = std::map<std::string, std::string>;
using objects_t = std::vector<object_t>;
int main() {
std::string str{R"({ "Main": [ { "obj1": "bar" }, { "obj2": "foo" } ] })"};
json j = json::parse(str);
auto objects{ j.at("Main").get<objects_t>() };
fmt::print("{}", objects);
}
// Outputs:
//
// [{"obj1": "bar"}, {"obj2": "foo"}]
CodePudding user response:
Yes, but the API gives an automatic way to do this by means of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE; it seems it would be like just defining a vector like this, but this program gives the error
[json.exception.out_of_range.403] key 'key' not found
program
#include <nlohmann/json.hpp>
#include <iostream>
#include <fstream>
using json = nlohmann::json;
struct key_value_t
{
std::string key;
std::string value;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(key_value_t, key, value);
int main()
{
try
{
std::string str{ R"({ "Main": [ { "obj1": "bar" }, { "obj2": "foo" } ] })" };
json js = json::parse(str);
std::vector<key_value_t> kv;
if (js.contains("Main"))
{
js.at("Main").get_to(kv);
}
}
catch (std::exception& e)
{
std::cout << e.what() << '\n';
}
return 0;
}