【问题标题】:How to parse boolean option in config file如何解析配置文件中的布尔选项
【发布时间】:2014-09-02 07:18:18
【问题描述】:

使用 boost 1_55,我有一个 bool_switch() 选项,定义为:

bpo::options_description opts;
opts->add_options()
    ("foo", bpo::bool_switch(), "Enable foo.");
opts_map = new bpo::variables_map;

并在命令行中解析:

bpo::store(bpo::parse_command_line(argc, argv, opts), *opts_map);

并且还通过以下方式在配置文件中解析:

ifstream ifs("foo.conf");
if (ifs.good()) {
    bpo::store(bpo::parse_config_file(ifs, opts), *opts_map);
    close(ifs);
}

问题在于,无论是否指定--foo,它都可以在命令行上正常工作,但是当我将其放入配置文件时,它始终是false(带有second.defaulted() == true)。我在配置文件中尝试了以下内容:

foo
foo=true
foo=1

其他类型的选项(例如 bpo::value<ANYTYPE>() 有或没有 composing())在命令行和配置文件中都可以正常工作,只有 bool_switch() 选项不起作用。

知道我做错了什么吗?或者您不能将bool_switch() 选项与parse_config_file() 一起使用吗?

编辑:

一种解决方法是将value() 类型与default_value()implicit_value() 一起使用:

opts->AddOptions()("foo", bpo::value<bool>()->default_value(false)->implicit_value(true), "Enable foo.");

【问题讨论】:

    标签: c++ parsing ini boost-program-options


    【解决方案1】:

    我目前使用的是 Boost 1.58,并且对配置文件中的布尔开关选项的支持工作得很好。

    配置文件(config.cfg):

    log=ON
    

    代码:

    #include <fstream>
    #include <boost/program_options.hpp>
    #include <iostream>
    
    namespace prog_opts = boost::program_options;
    
    //Notified function
    void option_verbose(bool opt) {
      std::cout << "Log ";
      if (opt)
        std::cout << "ON";
      else
        std::cout << "OFF";
    
      std::cout << "\n";
    }
    
    int main (int argc, char* argv[]) {
    
      prog_opts::options_description general("Options");
    
      general.add_options()
         ("log", prog_opts::bool_switch()->notifier(&option_verbose), "logging")
         ;
    
      // Assign the CLI args to the map
      prog_opts::variables_map cli_map;
    
      const prog_opts::basic_parsed_options< char >& cliopts = prog_opts::command_line_parser(argc, argv).options(general).run();
    
      prog_opts::store(cliopts , cli_map);
    
      // Get options from config
      std::ifstream infile("config.cfg", std::ifstream::in);
      store(parse_config_file(infile, general), cli_map);
    
      notify(cli_map);
    }
    

    从使用这个来看,行为似乎是:

    1. 如果您的选项出现在命令行上,则覆盖 配置文件。
    2. 如果命令行中没有您的选项,则使用配置文件选项值。

    在配置文件中 log=ON 的示例代码中,该选项将始终为 ON。将其设置为 OFF 时,只有在使用选项 --log 运行应用程序时才会启用该选项。

    希望这会有所帮助。

    【讨论】:

    • 它也适用于 boost 1.53,这是 CentOS 7 的默认设置。
    【解决方案2】:

    我不认为你正在尝试做的事情目前是允许的。 Vladimir,程序选项库的作者states

    我已经更改了 bool_switch,使其不接受任何参数。 这也解决了“arg (=0)”输出的问题。

    有一个可能的问题。对于命令行,我们很可能不会 想要布尔值的显式值。但在配置文件中,值为 始终存在。这是我知道单一选项的唯一情况 命令行和其他来源的描述有问题——如果 你用 bool_switch 描述一个选项,它不能在 配置文件。

    让我们看看这是否有问题。

    请注意,这个声明已经有将近 10 年的历史了,但是在检查 1.55 中的源代码时,我找不到任何证据表明它不再正确。

    【讨论】:

    • 那么一个有效的替代方案可能是:opts-&gt;AddOptions()("foo", bpo::value&lt;bool&gt;()-&gt;default_value(false), "Enable foo."); 也许?这是否仍然允许您在命令行上指定--foo
    • 看起来实际的解决方法是这样的(前提是您可以容忍缺少 'foo' 和 'foo=false' 相同)-opts-&gt;AddOptions()("foo", bpo::value&lt;bool&gt;()-&gt;default_value(false)-&gt;implicit_value(true), "Enable foo.");
    猜你喜欢
    • 2020-05-13
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 2011-10-12
    相关资源
    最近更新 更多