如何解析配置文件中的布尔选项

时间:2023-01-15 09:08:56

Using boost 1_55, I have a bool_switch() option, which is defined as:

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

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

And it is parsed on the command line by:

它在命令行上通过以下方式解析:

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

And also parsed in a config file by:

并通过以下方式解析配置文件:

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

The trouble is that it works fine on the command line by either specifying --foo or not, but it is always false (with second.defaulted() == true) when I put it in the config file. I have tried the following in the config file:

问题是它在命令行上运行正常,通过指定--foo或不指定 - 但是当我把它放在配置文件中时它总是假的(使用second.defaulted()== true)。我在配置文件中尝试了以下内容:

foo
foo=true
foo=1

Other types of options (e.g. bpo::value<ANYTYPE>() with or without composing()) work fine both on the command line and also in the config file, only bool_switch() options are not working.

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

Any idea what I'm doing wrong? Or can you not use bool_switch() options with parse_config_file()?

知道我做错了什么吗?或者你不能在parse_config_file()中使用bool_switch()选项吗?

EDIT:

编辑:

A workaround is to use a value() type with default_value() and implicit_value():

解决方法是使用带有default_value()和implicit_value()的value()类型:

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

2 个解决方案

#1


1  

I don't think what you're trying to do is presently allowed. Vladimir, the author of the program options library states

我不认为你现在想要做什么。程序选项库的作者弗拉基米尔说

I've changed bool_switch so that it does not accept any arguments. This also solves the problem with "arg (=0)" output.

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

There's one possible problem. For command line, we most likely don't want explicit value for bools. But in config file, the value is always present. This is the only case I know where single options description for command line and other sources is problematic -- if you describe an option with bool_switch, it can't be specified in config file.

有一个可能的问题。对于命令行,我们很可能不希望bools显式值。但是在配置文件中,值始终存在。这是我知道的唯一一种情况,其中命令行和其他源的单选项描述存在问题 - 如果您使用bool_switch描述选项,则无法在配置文件中指定。

Let's see if that's a problem.

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

Note that this statement is nearly 10 years old, but I couldn't find any evidence it's no longer true when inspecting the source code in 1.55.

请注意,这个陈述已有近10年的历史,但在1.55中检查源代码时,我找不到任何证据。

#2


2  

I'm currently using Boost 1.58 and support for boolean switch options in a config file works just fine.

我目前正在使用Boost 1.58并且在配置文件中支持布尔开关选项工作正常。

Config file (config.cfg):

配置文件(config.cfg):

log=ON

Code:

码:

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

From using this, it appears that the behavior is:

从使用它,似乎行为是:

  1. If your option is present on the command line then that overrides the config file.
  2. 如果您的选项出现在命令行中,则会覆盖配置文件。
  3. If your option is not present on the command line then the config file option value is used instead.
  4. 如果命令行中没有您的选项,则使用配置文件选项值。

In the example code with log=ON in the config file, the option will always be ON. With it set to OFF, the option will only be enabled when running your application with the option --log.

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

Hope this helps.

希望这可以帮助。

#1


1  

I don't think what you're trying to do is presently allowed. Vladimir, the author of the program options library states

我不认为你现在想要做什么。程序选项库的作者弗拉基米尔说

I've changed bool_switch so that it does not accept any arguments. This also solves the problem with "arg (=0)" output.

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

There's one possible problem. For command line, we most likely don't want explicit value for bools. But in config file, the value is always present. This is the only case I know where single options description for command line and other sources is problematic -- if you describe an option with bool_switch, it can't be specified in config file.

有一个可能的问题。对于命令行,我们很可能不希望bools显式值。但是在配置文件中,值始终存在。这是我知道的唯一一种情况,其中命令行和其他源的单选项描述存在问题 - 如果您使用bool_switch描述选项,则无法在配置文件中指定。

Let's see if that's a problem.

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

Note that this statement is nearly 10 years old, but I couldn't find any evidence it's no longer true when inspecting the source code in 1.55.

请注意,这个陈述已有近10年的历史,但在1.55中检查源代码时,我找不到任何证据。

#2


2  

I'm currently using Boost 1.58 and support for boolean switch options in a config file works just fine.

我目前正在使用Boost 1.58并且在配置文件中支持布尔开关选项工作正常。

Config file (config.cfg):

配置文件(config.cfg):

log=ON

Code:

码:

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

From using this, it appears that the behavior is:

从使用它,似乎行为是:

  1. If your option is present on the command line then that overrides the config file.
  2. 如果您的选项出现在命令行中,则会覆盖配置文件。
  3. If your option is not present on the command line then the config file option value is used instead.
  4. 如果命令行中没有您的选项,则使用配置文件选项值。

In the example code with log=ON in the config file, the option will always be ON. With it set to OFF, the option will only be enabled when running your application with the option --log.

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

Hope this helps.

希望这可以帮助。