2016-01-27 2 views
1

Я это набор данных в .txt лог-файл:Чтение данных из файла C++

2016-01-17 Red 1 2 2.252016-01-18 blue 3 1 1.34 

Я сохранил его в вектор, и код выглядит следующим образом:

while(!logFile.eof()) { 
    getline(logFile, l.date, ' '); 
    getline(logFile, l.color, ' '); 
    logFile >> l.minUsage; 
    logFile >> l.maxUsage; 
    logFile >> l.ratio; 
    logFile.ignore(1000, ' '); 

    log.push_back(l); 
} 

тип данных LOG является vector<Record> где Record - класс. Я хотел значения выглядеть следующим образом, когда я печатаю его:

2016-01-17 Red 1 2 2.25 
2016-01-18 blue 3 1 1.34 

, но вместо этого я получил этот результат:

2016-01-17 Red 1 2 2.25 
blue 3 1 0 1.34 

вторая строка не хранит значение даты от второго набор данных из файла .txt.

Как отделить 2.252016-01-18 от файла .txt от 2-х разных записей, таких как 2.25 и 2016-01-18?

+0

'2016-01-17 Красный 1 2 2.252016-01-18 синий 3 1 1.34' - это действительно ваши данные? Без разделителя? – LogicStuff

+1

Да, без разделителя. данные такие. поэтому я получил эту проблему – procatmer

+0

'getline' получает всю строку, которая, в соответствии с вашим примером, будет читать все данные для записи. Все остальные операции ввода файлов являются спорными. – AndyG

ответ

1

решен. поскольку значение ratio в файле журнала все 3-значное десятичное число, поэтому я изменил тип ratio, чтобы принять только 4 символа (пример: 2.13), затем я удалил строку logFile.ignore(1000, ' ');. он работает, и это дает мне результат, который я хотел.

+0

Даже лучше, чем моя подача. В бит 'logFile.ignore (1000, '');', это правило должно использовать 'numeric_limits :: max()' вместо строкового кода. – user4581301

2

Никогда не используйте !logFile.eof(), чтобы проверить конец ввода, он не возвращает true в конце ввода. Используйте getline вместо этого, что-то вроде:

while ((getline(logFile, l.date, ' ') && (getline(logFile, l.color, ' ')) { 
    // ... 
2

Вы можете построить простую государственную машину и извлечь пространственные разделители строк:

enum Group { DATE_ALONE, COLOR, NUM1, NUM2, NUM3_AND_DATE }; 

Group state = Group::DATE_ALONE; 
std::string str{}; 
while (logFile >> str) { 
    switch (state) { 
    case Group::DATE_ALONE: 
     auto date = makeDateFromString(str); 
     doSomethingWith(date); 
     state = Group::COLOR; 
     break; 
    case Group::COLOR: 
     auto color = makeColorFromString(str); 
     doSomethingWith(color); 
     state = Group::NUM1; 
     break; 
    // etc... 
    case Group::NUM3_AND_DATE: 
     auto num = makeNumFromString(str.substr(0, 4)); 
     doSomethingWith(num); 
     auto date = makeDateFromString(str.substr(4)); 
     doSomethingWith(date); 
     state = Group::COLOR; // Skip the `DATE_ALONE` state 
     break; 
    } 
} 
+0

Некоторая работа, требуемая со стороны ОП, чтобы это соответствовало их точным обстоятельствам, но правильная идея и достаточно близко для повышения. – user4581301

+0

Это моя цель :) –