2013-02-26 193 views
0

我試圖確定讀取配置文件的最佳方式。這種「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 

的名稱是有用戶知道他們正在定義的變量。我想讓我的程序只讀取實際的數字並跳過字符串。我知道我可以在我的程序中定義一大堆字符串,然後讓它們坐在那裏定義但顯然未被使用。有沒有辦法在跳過字符串時輕鬆讀取數字?

+1

沒有重新發明輪子的點:http://sourceforge.net/projects/libini/或http://sourceforge.net/projects/libconfig/ – 2013-02-26 21:27:08

+0

這是一個你正在使用的現有配置文件,或者你可以重新設計配置文件? – JBentley 2013-02-26 21:28:01

+0

它可以重新設計。 – ddavis 2013-02-26 21:35:22

回答

1

此方法不串存儲在所有(被要求在問題等):

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而不是讀取字符串,也不使用它。

+0

+1正是爲了完成問題所說的內容,但我認爲代碼不如使用臨時字符串變量的替代方法更清晰。 – us2012 2013-02-26 21:44:29

+0

@ us2012我同意:) – David 2013-02-26 21:45:39

+0

是的,感謝所有人的所有可用選項:) – ddavis 2013-02-26 21:47:42

4

顯而易見的解決方案有什麼問題?

string param_name; 
int param_value; 

while (fin >> param_name >> param_value) 
{ 
    .. 
} 

你可以在每次迭代後丟棄param_name同時存儲在任何需要它的param_value

3

當你讀出的字符串,只是不把它們存儲在任何地方:

std::vector<int> values; 
std::string discard; 
int value; 
while (file >> discard >> value) { 
    values.push_back(value); 
} 
0

您可以定義一個結構,然後超載istreamoperator>>吧:

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); 
2

我想我一定是過期張貼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