2015-12-19 2 views
0

В моем классе у меня есть этот метод ifstream Мне это нужно, чтобы прочитать файл и записать информацию в мои уже созданные объекты Что-то не так с кодом Сначала значение a.engiene вставляется с пробелом перед значением - «бензин»Что не так с моим методом ifstream?

И когда заданы значения второго объекта и третьего объекта, метод не присваивает правильное значение для каждого атрибута.

friend ifstream& operator>>(ifstream& in, Auto &a) 
     { 
      char temp[31]; 
      temp[0] = '\0'; 
      in.getline(temp, 30, ':'); 

      if (temp[0]) 
      { 
       in.getline(temp, 30, ':'); 
       delete[]a.engine; 
       a.engine = new char[strlen(temp) + 1]; 
       strcpy(a.engine, temp); 

       in.getline(temp, 30, ':'); 
       a.max_speed = atoi(temp); 

       in.getline(temp, 30, ':'); 
       a.engine_cc = atoi(temp); 

       in.getline(temp, 30, ':'); 
       a.avg_consumption_urban = atoi(temp); 

       in.getline(temp, 30, ':'); 
       a.avg_speed_urban = atoi(temp); 

       in.getline(temp, 30, ':'); 
       a.avg_consumption = atoi(temp); 

       in.getline(temp, 30, ':'); 
       a.avg_speed = atoi(temp); 

       return in; 
      } 
      else return in; 

Это, как я называю метод в основной:

 ifstream f1("autoc.txt", ios_base::in); 
       f1 >> auto1 >> auto2 >> auto3; 

Это файл данных:

auto1 
    engine: gasoline 
    max_speed: 250 
    engine_cc: 1980 
    avg_consumption_urban: 11 
    avg_speed_urban: 50 
    avg_consumption: 8 
    avg_speed: 100 
    auto2 
    engine: diesel 
    max_speed: 230 
    engine_cc: 1600 
    avg_consumption_urban: 9 
    avg_speed_urban: 50 
    avg_consumption: 6 
    avg_speed: 80 
    auto3 
    engine: hybrid 
    max_speed: 190 
    engine_cc: 1450 
    avg_consumption_urban: 7 
    avg_speed_urban: 50 
    avg_consumption: 4 
    avg_speed: 90 

Это окно вывода: http://imgur.com/tHe49se

Это не является дубликатом моего другого вопроса. У меня есть этот код, который почти работает. Мне нужно настроить правильное значение для моих атрибутов для каждого объекта.

+0

Что вы делаете? Вы должны ** пропустить имена свойств ** (чтение до ':') и ** затем ** прочитать значения. Пожалуйста, исправьте. – LogicStuff

+0

Возможный дубликат [Из файла, как я читаю из определенной точки на C++] (http://stackoverflow.com/questions/34345349/from-a-file-how-do-i-read-from-a -certain-point-in-c) – LogicStuff

+0

Это не дубликат. Там у меня был неопределенный вопрос. Здесь у меня есть этот код, который мне нужно исправить. Это почти работает. И как мне сделать то, что вы сказали? –

ответ

0
in.getline(temp, 30, ':'); 

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

in.getline(temp, 30); 

после каждого

in.getline(temp, 30, ':'); 

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

Я боюсь добавить более аккуратную версию этого (вы можете снова спросить о), поэтому я просто упомянул об этом (как и в ответе на ваш исходный вопрос). Речь идет об использовании std::string temp; и std::getline вместо std::istream::getline.

+0

Я добавил in.getline (temp, 30); как ты говорил. И для стартеров он пропускает первое значение для типа двигателя. Все еще работает неправильно. –

+0

Другие значения хороши? – LogicStuff

+0

Я не уверен, что мне нужно заменить, чтобы использовать строку temp. Я предполагаю, что мне нужно заменить мой temp [31] с помощью только строки temp ;? и измените in.getline (temp, 30, ':'); к чему? getline (temp, 30, ':'); ? –

0

Я считаю, что вы можете делегировать большую часть разбора самому STL. Формат ваших «авто» кажется фиксированным и имеет заданный порядок, что значительно упрощает подход к синтаксическому анализу (независимо от того, придерживаетесь ли вы при использовании «char [31]», неясно, но если вы не уверены, лучше с станд :: строку, как это имеет место с полем «имя» я добавил к Авто структуры)

рабочий образец:

#include <fstream> 
#include <locale> 
#include <iostream> 
#include <string> 


struct SeparatorReader: std::ctype<char> 
{ 
    template<typename T> 
    SeparatorReader(T &&seps): 
     std::ctype<char>(get_table(seps), true) {} 

    template<typename T> 
    std::ctype_base::mask const *get_table(T &&seps) { 
     auto rc = new std::ctype_base::mask[std::ctype<char>::table_size](); 
     for(auto &sep: seps) 
      rc[static_cast<unsigned char>(sep)] = std::ctype_base::space; 
     return &rc[0]; 
    } 
}; 


struct Auto 
{ 
    std::string name; 
    char engine[31]; 
    int max_speed; 
    int engine_cc; 
    int avg_consumption_urban; 
    int avg_speed_urban; 
    int avg_consumption; 
    int avg_speed; 

    Auto(const std::string &name) : name(name) {} 

    friend std::istream &operator >>(std::istream &is, Auto &a); 
    friend std::ostream &operator <<(std::ostream &os, const Auto &a); 
}; 

std::istream &operator >>(std::istream &is, Auto &a) 
{ 
    char tmp[31] = ""; 

    is >> tmp; is >> a.engine; // skip field name, read value 
    is >> tmp; is >> a.max_speed; 
    is >> tmp; is >> a.engine_cc; 
    is >> tmp; is >> a.avg_consumption_urban; 
    is >> tmp; is >> a.avg_speed_urban; 
    is >> tmp; is >> a.avg_consumption; 
    is >> tmp; is >> a.avg_speed; 

    return is; 
} 

std::ostream &operator <<(std::ostream &os, const Auto &a) 
{ 
    os << a.name << std::endl; 
    os << "engine: " << a.engine << std::endl; 
    os << "max_speed: " << a.max_speed << std::endl; 
    os << "engine_cc: " << a.engine_cc << std::endl; 
    os << "avg_consumption_urban: " << a.avg_consumption_urban << std::endl; 
    os << "avg_speed_urban: " << a.avg_speed_urban << std::endl; 
    os << "avg_consumption: " << a.avg_consumption << std::endl; 
    os << "avg_speed: " << a.avg_speed << std::endl; 

    return os; 
} 

int 
main(int argc, char *argv[]) 
{ 
    std::ifstream stream(argv[1]); 
    stream.imbue(std::locale(stream.getloc(), new SeparatorReader(" :\n"))); 

    std::string name; 
    while(stream >> name) { 
     Auto a(name); 
     stream >> a; 

     std::cout << "------------------------------" << std::endl; 
     std::cout << a; 
    } 
} 

Если мы передаем образец файла с входом образца ... выход:

------------------------------ 
auto1 
engine: gasoline 
max_speed: 250 
engine_cc: 1980 
avg_consumption_urban: 11 
avg_speed_urban: 50 
avg_consumption: 8 
avg_speed: 100 
------------------------------ 
auto2 
engine: diesel 
max_speed: 230 
engine_cc: 1600 
avg_consumption_urban: 9 
avg_speed_urban: 50 
avg_consumption: 6 
avg_speed: 80 
------------------------------ 
auto3 
engine: hybrid 
max_speed: 190 
engine_cc: 1450 
avg_consumption_urban: 7 
avg_speed_urban: 50 
avg_consumption: 4 
avg_speed: 90 
Смежные вопросы