从配置文件读取变量
问题描述:
我试图确定读取配置文件的最佳方式。这种“Parameters.cfg”文件就是定义值,是这种形式的:从配置文件读取变量
origin_uniform_distribution 0
origin_defined 1
angles_gaussian 0
angles_uniform_distribution 0
angles_defined 0
startx 0
starty 0
gap 500
nevents 1000
origin_uniform_distribution_x_min -5
origin_uniform_distribution_x_max 5
origin_uniform_distribution_y_min -5
origin_uniform_distribution_y_max 5
origin_defined_x 0
origin_defined_y 0
angles_gaussian_center 0
angles_gaussian_sigma 5
angles_uniform_distribution_x_min -5
angles_uniform_distribution_x_max 5
angles_uniform_distribution_y_min -5
angles_uniform_distribution_y_max 5
angles_defined_x 10
angles_defined_y 10
的名称是有用户知道他们正在定义的变量。我想让我的程序只读取实际的数字并跳过字符串。我知道我可以在我的程序中定义一大堆字符串,然后让它们坐在那里定义但显然未被使用。有没有办法在跳过字符串时轻松读取数字?
答
此方法不串存储在所有(被要求在问题等):
static const std::streamsize max = std::numeric_limits<std::streamsize>::max();
std::vector<int> values;
int value;
while(file.ignore(max, ' ') >> file >> value)
{
values.push_back(value);
}
它使用ignore而不是读取字符串,也不使用它。
答
显而易见的解决方案有什么问题?
string param_name;
int param_value;
while (fin >> param_name >> param_value)
{
..
}
你可以在每次迭代后丢弃param_name
同时存储在任何需要它的param_value
。
答
当你读出的字符串,只是不把它们存储在任何地方:
std::vector<int> values;
std::string discard;
int value;
while (file >> discard >> value) {
values.push_back(value);
}
答
您可以定义一个结构,然后超载istream
operator>>
吧:
struct ParameterDiscardingName {
int value;
operator int() const {
return value;
}
};
istream& operator>>(istream& is, ParameterDiscardingName& param) {
std::string discard;
return is >> discard >> param.value;
}
ifstream file("Parameters.cfg");
istream_iterator<ParameterDiscardingName> begin(file), end;
vector<int> parameters(begin, end);
答
我想我一定是过期张贴ctype方面忽略字符串和只读,我们关心的数据:
#include <locale>
#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
struct number_only: std::ctype<char> {
number_only() : std::ctype<char>(get_table()) {}
static mask const *get_table() {
static std::vector<mask> rc(table_size, space);
std::fill_n(&rc['0'], 10, digit);
rc['-'] = punct;
return &rc[0];
}
};
int main() {
// open the file
std::ifstream x("config.txt");
// have the file use our ctype facet:
x.imbue(std::locale(std::locale(), new number_only));
// initialize vector from the numbers in the file:
std::vector<int> numbers((std::istream_iterator<int>(x)),
std::istream_iterator<int>());
// display what we read:
std::copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
这样,无关的数据真的被真正地忽略了 - 在用我们的方面注入流之后,就好像字符串根本不存在。
+0
这封装行为,给它一个名称,并且是可重用的,而接受的解决方案需要重复每次你想要做到这一点,必须阅读才能被理解。此外,这适用于任何容器构造函数或迭代器算法。在我看来,这好得多。 – 2013-02-27 08:29:33
没有重新发明轮子的点:http://sourceforge.net/projects/libini/或http://sourceforge.net/projects/libconfig/ – 2013-02-26 21:27:08
这是一个你正在使用的现有配置文件,或者你可以重新设计配置文件? – JBentley 2013-02-26 21:28:01
它可以重新设计。 – ddavis 2013-02-26 21:35:22