我正在使用boost :: program_options加载命令行参数。现在,我想另外加载具有相同参数集的配置文件。我以非常标准的方式使用它:
ifstream ifs(filename.c_str());
if (ifs) {
po::store(po::parse_config_file(ifs, optionsDescription), vm);
po::notify(vm);
}
问题是parse_config_file接受以下标准格式的ini文件:
key1=value
key2 = value
但是我的文件没有使用“等号”来分隔键和值,而只使用了空格和/或制表符,如下所示:
key1 value
key2 value
出于兼容性原因,我需要保留此格式。有什么办法可以通过boost program_options实现这一目标吗? 我已经找到了command_line分析的样式选项,但是parse_config_file似乎没有这样的东西。
答案 0 :(得分:1)
根据source code,boost似乎在明确寻找=
符号。
因此,没有直接的方法来处理文件格式。您可能必须更改boost源或将文件加载到内存并作为命令行输入处理值。
else if ((n = s.find('=')) != string::npos) {
string name = m_prefix + trim_ws(s.substr(0, n));
string value = trim_ws(s.substr(n+1));
bool registered = allowed_option(name);
if (!registered && !m_allow_unregistered)
boost::throw_exception(unknown_option(name));
found = true;
this->value().string_key = name;
this->value().value.clear();
this->value().value.push_back(value);
this->value().unregistered = !registered;
this->value().original_tokens.clear();
this->value().original_tokens.push_back(name);
this->value().original_tokens.push_back(value);
break;
}
答案 1 :(得分:0)
我需要类似的东西,但是输入配置文件是一个基本的CSV文件(即,不支持使用引号来处理包含逗号的值)。
我的解决方案基于miradham上面的内容,是通过filtering_istream
传递输入文件流并应用一个简单的正则表达式过滤器,该过滤器将','转换为'='。
如果将来我们需要用逗号添加值,那么我可能必须实现自己的filtering_istream
(我知道这是一个模板)来处理这种更复杂的情况。
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/regex.hpp>
#include <boost/program_options.hpp>
#include <boost/regex.hpp>
...
// do we have a config file?
if (vm.count("config"))
{
std::ifstream fConfig{ vm["config"].as<std::string>().c_str() };
if (fConfig)
{
// prep_config = filtered stream, replacing ',' with '='
boost::iostreams::filtering_istream prep_config;
prep_config.push(boost::iostreams::regex_filter{ boost::regex{","}, "="});
prep_config.push(fConfig);
po::store(parse_config_file( prep_config, desc), vm);
po::notify(vm);
}
else
{
std::cerr << "Could not open the configuration file - ignoring.\n";
}
}
// drop through to the main configuration interpretation