ifstream как начать чтение строки с определенной строки с помощью С++

Я использую ifstream для анализа файла в коде С++. Я не могу использовать seekg() и tellg() для перехода к определенной строке кода.

В частности, я хотел бы прочитать строку с помощью метода getLine из определенной позиции файла. Позиция сохранена в предыдущей итерации.


person rebatoma    schedule 08.09.2015    source источник
comment
Что вы подразумеваете под позицией, сохраненной в предыдущей итерации? В каком смысле вы повторяетесь? Если вы перебираете файл, вы можете вызвать getline(my_ifstream, my_string) для чтения каждой строки по очереди. Если у вас есть целочисленный номер строки и вы хотите перейти к этой строке из фактически несвязанной позиции в файле, вам нужно прочитать из некоторой известной позиции строки (например, строки 1 в позиции 0) и подсчитать новые строки по мере продвижения.   -  person Tony Delroy    schedule 08.09.2015
comment
@TonyD Да, я повторяю файл, но в какой-то момент я останавливаюсь и работаю с другим файлом. Затем после этого я хотел бы перезапустить с последней строки, прочитанной перед использованием «getline (my_ifstream, my_string)» с первым файлом.   -  person rebatoma    schedule 08.09.2015
comment
каждый ifstream поддерживает свою собственную позицию ввода - если вы используете разные объекты ifstream для разных файлов, вы можете продолжить чтение строк, где вы остановились в первом файле, без каких-либо осложнений. Если вы действительно хотите использовать тот же ifstream, вы можете вызвать tellg чтобы получить текущую позицию, и seekg позже, чтобы восстановить ее.   -  person Tony Delroy    schedule 08.09.2015
comment
@TonyD Спасибо за вашу помощь.   -  person rebatoma    schedule 08.09.2015


Ответы (2)


Вам просто нужно пропустить необходимое количество строк. Лучший способ сделать это — игнорировать строки с помощью std::istream::ignore

for (int currLineNumber = 0; currLineNumber < startLineNumber; ++currLineNumber){
    if (addressesFile.ignore(numeric_limits<streamsize>::max(), addressesFile.widen('\n'))){
        //just skipping the line
    } else {
        // todo: handle the error
    }
}

Первый аргумент — максимальное количество символов для извлечения. Если это именно numeric_limits::max(), ограничений нет.

Вы должны использовать is вместо std::getline из-за лучшей производительности.

person Arthur P. Golubev    schedule 08.09.2015
comment
Итак, я должен использовать это, чтобы пропустить общее количество строк, а затем вызвать getLine , чтобы прочитать следующую строку. Это правильно? - person rebatoma; 08.09.2015
comment
@ Маттиа, да, ты прав. Вам нужно прочитать столько строк, сколько требуется, чтобы заархивировать строку, которую вы хотите прочитать. Сам файл не содержит каких-либо мета(вспомогательных)-данных, которые могли бы помочь сразу перейти в нужную позицию. Если вы не собираете такие метаданные самостоятельно, подсчет строк при считывании — единственный выход. Существенным фактом является то, что использование ignore вместо getline намного эффективнее. - person Arthur P. Golubev; 08.09.2015
comment
Отлично, вроде работает нормально. Спасибо за вашу помощь. - person rebatoma; 08.09.2015

Специфических функций С++ вроде "seekline" для ваших нужд вроде нет, и я вижу два пути решения этой задачи:

  1. Предварительно вы можете расширить каждую строку в текстовом файле пробелами, чтобы достичь постоянной длины L. Затем, чтобы найти нужную строку N, просто используйте seekg со смещением L * N.
  2. Этот способ более сложный. Вы можете создать вспомогательный бинарный файл, каждый его байт будет содержать длину каждой строки исходного файла. Этот вспомогательный файл является своего рода базой данных. Затем вы должны загрузить этот двоичный файл в массив вашей программы на этапе инициализации. Смещение требуемой строки в текстовом файле должно быть рассчитано как сумма первых элементов массива N. Конечно, необходимо одновременно обновлять вспомогательный файл и исходный файл.

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

person boeing777    schedule 08.09.2015