使用boost :: program_options解析配置文件

时间:2012-07-12 12:10:51

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

美好的一天,

我写了一个类来通过boost :: program_options来解析配置文件。这是我的(缩短):

namespace nsProOp = boost::program_options;
nsProOp::variables_map m_variableMap;
nsProOp::options_description m_description;



// To add options to the variableMap, e.g. "addOption<int>("money_amount");"
template <class T>
    void addOption(const std::string& option, const std::string& helpDescription = "") {
        m_description.add_options()(option.c_str(), nsProOp::value<T > (), helpDescription.c_str());
    }



// And this is how i actually read the file:
void ConfigFile::parse() {
    std::ifstream file;
    file.open(m_pathToFile.c_str());

    nsProOp::store(nsProOp::parse_config_file(file, m_description, true), m_variableMap);
    nsProOp::notify(m_variableMap);      
}

好的,这很好用。但我希望能够再次解析同一个文件,以便我总是使用用户提供的最新条目!增强文档说的是“商店”:

  

“在'm'中存储'选项'中定义的所有选项。           如果'm'已经具有选项的非默认值,那么该值           即使'options'指定了一些值,也不会改变。“

所以,如果我再次调用“parse()”则没有任何反应,因为m_variableMap已被填充。我尝试调用m_variableMap.clear()并不能解决我的问题,因此存储只能在第一次工作。

有人给我建议吗?如果我的问题不清楚,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:11)

至少在提升1.50时,variables_map::clear()将允许通过store正确地重新填充变量地图。另一种解决方案可以在至少提升1.37之前工作,在调用store之前将默认构造变量映射分配到变量映射中。

void ConfigFile::parse() {
  std::ifstream file;
  file.open(m_pathToFile.c_str());
  m_variableMap = nsProOp::variables_map(); // Clear m_variableMap.
  nsProOp::store(nsProOp::parse_config_file(file, m_description, true), 
                 m_variableMap);
  nsProOp::notify(m_variableMap);      
}

以下是一个示例程序:

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

namespace po = boost::program_options;

void write_settings(const char* value)
{
  std::ofstream settings_file("settings.ini");
  settings_file << "name = " << value;
}

void read_settings(po::options_description& desc,
                   po::variables_map& vm)
{
  std::ifstream settings_file("settings.ini");

  // Clear the map.
  vm = po::variables_map();

  po::store(po::parse_config_file(settings_file , desc), vm);
  po::notify(vm);    
}

int main()
{
  std::string name;

  // Setup options.
  po::options_description desc("Options");
  desc.add_options()
    ("name", po::value<std::string>(&name), "name");
  po::variables_map vm;

  // Write, read, and print settings.
  write_settings("test");
  read_settings(desc, vm);
  std::cout << "name = " << name << std::endl;

  // Write, read, and print newer settings.
  write_settings("another test");
  read_settings(desc, vm);
  std::cout << "name = " << name << std::endl;
}

产生以下输出:

name = test
name = another test