2013-02-26 12 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/ –

+0

Это уже существующий файл конфигурации, с которым вы работаете, или вы можете переконфигурировать конфигурационный файл? – JBentley

+0

Его можно перепроектировать. – ddavis

ответ

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

+0

@ us2012 Я согласен :) – David

+0

Да, спасибо всем за все полезные параметры :) – ddavis

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

Это инкапсулирует поведение, указывая его имя и повторно используется, тогда как принятое решение нужно повторять каждый раз, когда вы хотите делайте это, и его нужно читать, чтобы его понимали. Кроме того, это работает с любыми конструкторами контейнеров или итераторами. На мой взгляд, гораздо лучше. –

Смежные вопросы