微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用INI和命令行使用boost :: program_options的明智方法?

如何解决用INI和命令行使用boost :: program_options的明智方法?

我想编写一个程序来解析配置文件,并允许命令行覆盖那里写的内容。所以我可以有一个配置文件,上面写着:

[section1]
opt1=42

[section2]
opt2=17

然后,我可以运行以下命令:

./so --opt2=3

该程序将opt1的值分别设置为42,opt2和3。我使用以下程序进行尝试:

#include <fstream>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

int main(int argc,char *argv[]) {
    po::options_description options1("section1");
    options1.add_options()
            ("opt1",po::value<int>(),"Option 1");

    po::options_description options2("section2");
    options2.add_options()
            ("opt2","Option 2");

    po::options_description options;
    options.add(options1);
    options.add(options2);

    po::variables_map values;
    po::store( po::command_line_parser( argc,argv ).options(options).run(),values );

    std::ifstream iniFile( "options.ini" );

    po::store(
            parse_config_file( iniFile,options ),values );
}

这当然是行不通的。 Boost :: program_options希望将opt1下的section1称为section1.opt1。但是,如果这样做,我的程序将很难在两个方面进行维护:

  • 我需要定义两个options_description一个用于INI,一个用于命令行。
  • 由于选项的键现在不同,因此我需要手动合并两者。

是否有一种无需手动完成工作的方法

解决方法

最简单的解决方案是不使用这些部分。选项说明中的“节”与ini文件中的节之间可能会有一些混淆。

ini文件中的各节仅 引用以嵌入句点命名的选项:"section1.opt1"。因此,您只需将配置文件写为:

opt1=42

# perhaps with a comment
opt2=17

查看 Live On Coliru

#include <boost/program_options.hpp>
#include <fstream>
#include <iostream>

namespace po = boost::program_options;

int main(int argc,char* argv[]) {
    po::options_description options;
    options.add_options()
        ("opt1",po::value<int>(),"Option 1")
        ("section2.opt2","Option 2");

    std::cout << options << "\n";

    po::variables_map values;
    po::store(po::parse_command_line(argc,argv,options),values);

    std::ifstream iniFile("options.ini");

    po::store(parse_config_file(iniFile,values);

    auto report = [&values](char const* name) {
        if (auto opt = values[name]; !opt.empty())
            std::cout << name << ": " << opt.as<int>() << "\n";
    };

    report("opt1");
    report("opt2");
    report("section1.opt1");
    report("section2.opt2");
}

打印

echo "opt1=42" >> options.ini; ./a.out --section2.opt2 99
  --opt1 arg            Option 1
  --section2.opt2 arg   Option 2

opt1: 42
section2.opt2: 99

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?