Использование getline при чтении из текстового файла - PullRequest
1 голос
/ 31 августа 2010

Я изначально строю механизм, подобный индексу, читаю каждую строку текстового файла, используя getline, проверяю, соответствует ли оно известному объявлению заголовка (string.compare), и сохраняю позицию Tellg как индекс до этой точки.Тогда я собираюсь использовать seekg (index, ios :: beg) для поиска места в файле, где находится заголовок.После прочтения файла один раз при построении моего индекса и вызове seekg (0, ios :: beg) следующая строка getline возвращает пустую строку, где я ожидаю увидеть первую строку в файле.

часть моегокод ниже, чтобы лучше подчеркнуть мою проблему

//build the index
while (! m_fileIn.eof())
{
   getline (m_fileIn,lineRead);
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

// start reading the file data
m_fileIn.seekg(0,ios::beg);
//read first line (title)

функция getLineID возвращает int в зависимости от результата сравнения строк.

- это неправильное использование getline, если мне нужно повторночитать файл?

Ответы [ 2 ]

2 голосов
/ 31 августа 2010

Ваша проблема вызвана тем, что в потоке установлен плохой бит.
Операции с потоком будут игнорироваться до тех пор, пока не будет сброшен плохой бит.

// After the loop reset the Bad Bits.
m_fileIn.clear()

Примечание: плохой битэто одно из многих состояний ошибки, включая EOF

Но это не ваши основные проблемы:

Вы используете Classic anti pattern для чтения файла:
Скорее используйте это.

while (getline (m_fileIn,lineRead))
{
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

Проблема в том, что EOF не установлен, пока вы не прочитаете за ним.
Последнее действительное чтение читает UPTO, но не за EOF (следовательно, EOF не установлено).

Итакрассмотрим ситуацию, когда вы прочитали последнюю строку в файле.EOF не был установлен, поскольку вы не читали мимо него.Итак, цикл введен.Теперь вы выполняете getline ().Это пытается прочитать прошедшее EOF, так как нет абсолютно никаких данных для чтения (ни одного байта).Так что getline () завершается ошибкой, теперь вы вызываете getlineID () с помощью lineRead, значение которого не определено (в стандарте не говорится, что происходит с lineRead, когда выполняется условие EOF; но, вероятно, значение последней строки читается, как вам кажетсячтобы сбросить его внутри цикла).

Другая проблема с этим кодом заключается в проверке только на EOF.Что происходит, когда возникает другой тип ошибки?Цикл фактически застревает в бесконечном цикле;это потому, что когда установлен флаг ошибки, чтение больше не происходит, поэтому вы никогда не сможете достичь EOF.

while (! m_fileIn.eof())
{
   getline (m_fileIn,lineRead)
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

Решение состоит в том, чтобы выполнить операцию чтения в тесте цикла while.Это работает, потому что getline () возвращает поток, переданный в качестве первого параметра.Поэтому поток используется в логическом контексте.Когда поток используется в логическом контексте, он преобразуется в тип, который может использоваться как логический;значение этого объекта эквивалентно true, если ошибок нет, и false в противном случае.

В этом случае выполняется попытка чтения, но при неудаче цикл никогда не вводится.

1 голос
/ 31 августа 2010

После публикации здесь и просмотра различных веб-сайтов, я добавил строку

m_fileIn.clear();

перед строкой

getline (m_fileIn,lineRead);

очистив флажки ошибок (я предполагаю, что все ошибки) я смог продолжить как обычно.

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

...