有没有办法打印配置文件的升级程序选项

时间:2011-01-16 00:55:30

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

我正在使用boost :: program_options从配置文件中获取参数。

我知道我可以手动创建一个文件,程序选项会解析它。但我正在寻找程序自动生成文件的方法。意思是打印出选项的名称及其值。例如:

>./main 

没有选项会生成类似于此

的init.cfg
[wave packet]
width = 1
position = 2.0
[calculation parameters]
levels = 15

然后我会进入该文件使用文本编辑器更改值并使用此文件:

>./main init.cfg

解决这个问题的好方法是让variables_map拥有operator<<。这样我就可以把它写到文件中。改变价值观。读取文件。所有格式相同,无需编写每一行。

我在文档或示例中找不到类似的内容。如果可能,请告诉我

编辑:Sam Miller展示了如何分段解析ini文件。但是,从boost :: program_options :: variables_map vm获取值仍然存在问题。 我尝试了以下

  for(po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it)
  {
    if(it->first!="help"&&it->first!="config")
    cout << "first - " << it->first << ", second - " << it->second.value() << "\n";
  }

而不是it->second.value(),出错了。我也试过it->second。我也有一个错误:

icpc -lboost_serialization -lboost_program_options -c programOptions.cc
programOptions.cc(60): error: no operator "<<" matches these operands
            operand types are: std::basic_ostream<char, std::char_traits<char>> << boost::any
      cout << "first - " << it->first << ", second - " << it->second.value() << "\n";
                                                       ^

compilation aborted for programOptions.cc (code 2)
make: *** [programOptions.o] Error 2

如果我使用it->second.as<int>()我得到的值是正确的,但并非我的所有值都是整数,一旦我达到双倍,程序会崩溃:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >'
  what():  boost::bad_any_cast: failed conversion using boost::any_cast

2 个答案:

答案 0 :(得分:12)

我没有办法使用我所知道的program_options。您可以将属性树库用于write the ini file

这是一个简短的例子:

macmini:stackoverflow samm$ cat property.cc 
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

#include <iostream>

int
main()
{
    using boost::property_tree::ptree;

    ptree root;

    ptree wave_packet;
    wave_packet.put( "width", "1" );
    wave_packet.put( "position", "2.0" );

    ptree calculation_parameters;
    calculation_parameters.put( "levels", "15" );

    root.push_front(
            ptree::value_type( "calculation parameters", calculation_parameters )
            );
    root.push_front(
            ptree::value_type( "wave packet", wave_packet )
            );

    write_ini( std::cout, root );

    return 0;
}

macmini:stackoverflow samm$ g++ property.cc 
macmini:stackoverflow samm$ ./a.out
[wave packet]
width=1
position=2.0
[calculation parameters]
levels=15
macmini:stackoverflow samm$ 

答案 1 :(得分:0)

据我所知,这是关于如何根据给定的option_description编写配置文件。

以下是可能的解决方案,如何将一个options_description写入配置文件。它涉及每个参数都有一些默认值的事实。

void SaveDefaultConfig()
{
    boost::filesystem::ofstream configFile(configFilePath_);
    auto descOptions = algorithmsDesc_.options();
    boost::property_tree::ptree tree;

    for (auto& option : descOptions)
    {
        std::string name = option->long_name();
        boost::any defaultValue;
        option->semantic()->apply_default(defaultValue);

        if (defaultValue.type() == typeid(std::string))
        {
            std::string val = boost::any_cast<std::string>(defaultValue);
            tree.put(name, val);
        }
        ///Add here additional else.. type() == typeid() if neccesary
    }

    //or write_ini
    boost::property_tree::write_json(configFile, tree);
}

这里的algorithmsDesc是boost :: program_options :: options_description,你可以在这里描述如下选项:

algorithmsDesc_.add_options()
    ("general.blur_Width", po::value<int>(&varWhereToStoreValue)->default_value(3), "Gaussian blur aperture width")

问题是如果您需要配置文件中的部分。 options_description没有方法来获取通过它的构造函数传递的标题。获取它的方法是将它从print()生成的输出流中删除:

std::string getSectionName()
{
    std::stringstream ss;
    algorithmDesc_.print(ss)

    std::string caption;
    std::getline(ss,caption)

    //cut last ':'
    return caption.substr(0, caption.size() - 1)
}

将它们组合在一起非常简单。