C++ 在INI和命令行中使用boost::program_选项的合理方法?

C++ 在INI和命令行中使用boost::program_选项的合理方法?,c++,boost,boost-program-options,C++,Boost,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::p

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

[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", po::value<int>(), "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 );
}
当然,这是行不通的。program_options希望将section1下的opt1称为section1.opt1。但是,如果我这样做,我的计划就很难在两个方面得到维护:

我需要定义两个选项描述,一个用于INI,另一个用于命令行。 由于选项的键现在不同了,我需要手动合并这两个选项。
有没有一种方法可以在不手动操作的情况下实现这一点?

简单的解决方案是,不要使用这些部分。选项说明中的部分与ini文件中的部分之间可能存在一些混淆

ini文件中的部分仅指以嵌入句点命名的选项:section1.opt1。因此,您只需将配置文件编写为:

opt1=42

# perhaps with a comment
opt2=17
看到了吗


如果你仍然需要这些部分,你可以像我一样做一些后处理,或者答案完全忽略了这个问题。如果回答说你不能这样做,那就没什么帮助了。您的回答本质上是说获取节的解决方案是不使用节。你的回答是对问题中信息的重复。好的。这是一个苛刻的解读,但我很欣赏这个解释。我更仔细地分析了这个问题,因为这并没有达到我的预期/希望,这就是为什么我放大了可能产生混淆的原因描述部分不是部分。因为您的问题只集中在更改/一侧/描述上,所以我选择了另一种方式来更改配置文件,它确实满足所有规定的要求。我承认,改变可能不是你的初衷。我想结果是,根据你自己的评估,答案对你帮助不大。我认为这是出于礼节,通常不需要投反对票。很抱歉,我在回答的措辞中造成了任何混乱,沟通很困难。干杯
#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", po::value<int>(), "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, options), 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