使用json文件的C++ Boost程序选项

wz1wpwve  于 2022-12-20  发布在  其他
关注(0)|答案(3)|浏览(182)

可以使用升压程序选项库:http://www.boost.org/doc/libs/1_64_0/doc/html/program_options.html
读取json格式的文件作为输入文件?
或者,如果我有一些配置在json一样的文件,我需要自己解析它,例如:http://www.boost.org/doc/libs/1_64_0/doc/html/property_tree.html

6vl6ewon

6vl6ewon1#

我也遇到过同样的问题,下面是我基于property_tree为program_options库实现的JSON解析器:

template <class charT> void parseChildren(std::string prefix, boost::property_tree::ptree& tree, boost::program_options::parsed_options& options)
{
    if (tree.size() == 0)
    {
        //cut first dot
        std::basic_string<charT> name = prefix.substr(1);
        std::basic_string<charT> value = tree.data();

        boost::program_options::basic_option<charT> opt;
        opt.string_key = name;
        opt.value.push_back(value);
        opt.unregistered = (options.description->find_nothrow(name, false) == nullptr);
        opt.position_key = -1;
        options.options.push_back(opt);
    }
    else
    {
        for (auto it = tree.begin(); it != tree.end(); ++it)
        {
            parseChildren<charT>(prefix + "." + it->first, it->second, options);
        }
    }
}

template <class charT>
void parseJsonOptions(std::basic_istream<charT>& is, boost::program_options::parsed_options& options)
{
        boost::property_tree::basic_ptree<std::basic_string<charT>, std::basic_string<charT>> pt;
        boost::property_tree::read_json(is, pt);

        parseChildren<charT>(std::basic_string<charT>(), pt, options);
}

template <class charT>
boost::program_options::basic_parsed_options<charT> parse_json_config_file(std::basic_istream<charT>& is, const boost::program_options::options_description& desc, bool allow_unregistered = false)
{     
    // do any option check here

    boost::program_options::parsed_options result(&desc);
    parseJsonOptions(is, result);

    return boost::program_options::basic_parsed_options<charT>(result);
}

像这样使用它:

po::variables_map vm;
std::ifstream configFileStream(configFilePath_.generic_string());

store(parse_json_config_file(configFileStream, algorithmsDesc_), vm);
notify(vm);
mf98qq94

mf98qq942#

可以使用升压程序选项库:http://www.boost.org/doc/libs/1_64_0/doc/html/program_options.html
读取json格式的文件作为输入文件?
不可以,但是如果您为它编写一个解析器组件,就可以
或者,如果我有一些配置在json一样的文件,我需要自己解析它,例如:http://www.boost.org/doc/libs/1_64_0/doc/html/property_tree.html
你可以。一定要检查它的局限性。另外,要注意"json like"之类的东西。任何非标准的JSON都有可能破坏解析器,所以如果它不是标准的,你可能需要手动处理它。

j7dteeu8

j7dteeu83#

我修改了提供的solutionsparseChildren模板,以支持JSON数组文字的解析:

template <class charT>
void parseChildren(std::string const& prefix, boost::property_tree::ptree& tree,
                   boost::program_options::parsed_options& options) {
  if (tree.empty()) {
    // remove first dot
    std::basic_string<charT> name = prefix.substr(1);
    // remove last dot if present
    if (name.back() == '.') {
      name.pop_back();
    }
    std::basic_string<charT> value = tree.data();

    boost::program_options::basic_option<charT> opt;
    opt.string_key = name;
    opt.value.push_back(value);
    opt.unregistered =
        (options.description->find_nothrow(name, false) == nullptr);
    opt.position_key = -1;
    // append value to existing option-key if it exists
    for (auto& o : options.options) {
      if (o.string_key == name) {
        o.value.push_back(value);
        return;
      }
    }
    options.options.push_back(opt);
  } else {
    for (auto it = tree.begin(); it != tree.end(); ++it) {
      parseChildren<charT>(prefix + "." + it->first, it->second, options);
    }
  }
}

现在,解析以下JSON应该会在所需的CLI选项输出中解析:

{
   "opt-1": "value-1",
   "opt-2": ["value-2-1", "value-2-2"]
}

使用时:

po::options_description opts("CLI options");
  opts.add_options()                                     //
      ("opt-1", po::value<std::string>(), "opt-1 desc")  //
      ("opt-2", po::value<std::vector<std::string>>()->multitoken(), "opt-2 desc")

相关问题