'json config reader in C++
I have this config data in this json,
{
"difficulty":-1,
"damage":100,
"infinite":true,
"tilewidth":16,
"type":"map",
"version":"1.2.4"
}
and i want to store these variables in my program.I cant use a Map cause there isn't a fixed type to read (int,string,bool)...
using JSON = nlohmann::json;
/* struct Configs final {
int difficulty;
int damage;
bool infinite;
int tilewidth;
std::string type;
std::string version;
}; */
int main(void) {
JSON j;
std::ifstream in("./assets/Map.json");
in >> j;
for (auto &el : j.items()) {
std::cout << el.key() << " : " << el.value() << "\n";
}
return 0;
}
What are some smart ways of doing this?
Solution 1:[1]
I prefer to provide a from_json
function. It could look like this:
struct Configs final {
int difficulty;
int damage;
bool infinite;
int tilewidth;
std::string type;
std::string version;
};
void from_json(const json& j, Configs& c) {
j.at("difficulty").get_to(c.difficulty);
j.at("damage").get_to(c.damage);
j.at("infinite").get_to(c.infinite);
j.at("tilewidth").get_to(c.tilewidth);
j.at("type").get_to(c.type);
j.at("version").get_to(c.version);
}
You could then populate a Configs
like this:
in >> j;
auto conf = j.get<Configs>();
Solution 2:[2]
You're gonna have to dig into the documentation for your JSON library. Figure out how to check the types of each member you've parsed. Docs here recommend making a from_json
function for your class/struct type. It looks like they provide some helpful macros for connecting JSON fields to your class/struct fields, like NLOHMANN_DEFINE_TYPE_NON_INSTRUSIVE
This seems to work alright
I'm assuming from_json
is going to throw. Make sure you handle errors.
#include <string>
#include <nlohmann/json.hpp>
using namespace std::string_literals;
static const auto sampleJson = R"(
{
"difficulty":-1,
"damage":100,
"infinite":true,
"tilewidth":16,
"type":"map",
"version":"1.2.4"
}
)"s;
struct Configs final {
int difficulty;
int damage;
bool infinite;
int tilewidth;
std::string type;
std::string version;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Configs, difficulty, damage, infinite, tilewidth, type, version);
using JSON = nlohmann::json;
int main(void)
{
try {
auto j = JSON::parse(sampleJson);
Configs c;
from_json(j, c);
}
catch (...) {
return 1;
}
return 0;
}
Solution 3:[3]
You can use my command line tool json-cpp-gen to automatically generate a JSON parser class from the Configs
structure definition. (It might not recognize the final
keyword so you might have to remove that.) All you have to do is pass it a configuration file containing
{
"inputs": [ "Configs.h" ],
"parsers": [ {
"name": "ConfigsParser",
"types": [ "Configs" ],
"headerOutput": "ConfigsParser.h",
"sourceOutput": "ConfigsParser.cpp"
} ],
}
where Configs.h is the relative path to the file where the sturcture is defined and then you can use the generated parser class as ConfigsParser::parse(configsOutput, jsonString);
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Detheroc |