【问题标题】:json config reader in C++C++ 中的 json 配置阅读器
【发布时间】:2022-01-15 22:46:12
【问题描述】:

我在这个 json 中有这个配置数据,

{
    "difficulty":-1,
    "damage":100,
    "infinite":true,
    "tilewidth":16,
    "type":"map",
    "version":"1.2.4"
}

我想将这些变量存储在我的程序中。我不能使用 Map,因为没有固定类型可供读取 (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;
}

有哪些聪明的方法可以做到这一点?

【问题讨论】:

  • 也许是std::map&lt;std::string, std::any&gt;,如果你知道所有可能的类型std::variant而不是std::any
  • 这些字段是否已修复,或者某些字段是否缺失而其他字段是否可以添加等?

标签: c++ json configuration


【解决方案1】:

我更喜欢提供from_json 函数。它可能看起来像这样:

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

然后您可以像这样填充Configs

in >> j;
auto conf = j.get<Configs>();

【讨论】:

    【解决方案2】:

    您将不得不深入研究 JSON 库的文档。弄清楚如何检查您解析的每个成员的类型。 Docs here recommend making a from_json 用于您的类/结构类型的函数。看起来他们提供了一些有用的宏来将 JSON 字段连接到您的类/结构字段,例如 NLOHMANN_DEFINE_TYPE_NON_INSTRUSIVE

    这似乎没问题

    我假设from_json 会抛出。确保您处理错误。

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

    【讨论】:

      【解决方案3】:

      您可以使用我的命令行工具json-cpp-gen 自动从Configs 结构定义生成JSON 解析器类。 (它可能无法识别 final 关键字,因此您可能必须删除它。)您所要做的就是传递一个包含

      的配置文件
      {
          "inputs": [ "Configs.h" ],
          "parsers": [ {
              "name": "ConfigsParser",
              "types": [ "Configs" ],
              "headerOutput": "ConfigsParser.h",
              "sourceOutput": "ConfigsParser.cpp"
          } ],
      }
      

      其中 Configs.h 是定义结构的文件的相对路径,然后您可以将生成的解析器类用作 ConfigsParser::parse(configsOutput, jsonString);

      【讨论】:

        猜你喜欢
        • 2012-02-16
        • 2016-02-14
        • 1970-01-01
        • 1970-01-01
        • 2013-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多