2015-09-08 2 views
0

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

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

+1

Что вы подразумеваете под * «Позиция сохранена в предыдущей итерации». *? В каком смысле вы итерируете? Если вы выполняете итерацию по файлу, вы можете вызвать 'getline (my_ifstream, my_string)' для чтения каждой строки по очереди. Если у вас есть целостный номер строки и вы хотите перейти к этой строке из позиции, не имеющей отношения к файлу, вам нужно прочитать ее из некоторой позиции известной строки (например, строки 1 в позиции 0) и подсчитать вверх по новым линиям по мере продвижения. –

+0

@TonyD Да, я повторяю файл, но в какой-то момент я останавливаюсь и работаю в другом файле. Затем после этого я хотел бы перезапустить из последней строки, прочитанной перед использованием 'getline (my_ifstream, my_string)' с первым файлом. – Mattia

+2

каждый 'ifstream' поддерживает свою собственную позицию ввода - если вы используете разные объекты' ifstream' для разных файлов, вы можете продолжить чтение строк, в которых вы остановились в первом файле без каких-либо осложнений. Если вы действительно хотите использовать один и тот же 'ifstream', вы можете вызвать [' tellg'] (http://en.cppreference.com/w/cpp/io/basic_istream/tellg), чтобы получить текущую позицию, и 'seekg 'позже, чтобы восстановить его. –

ответ

3

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

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(), ограничений нет.

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

+0

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

+0

@Mattia, да, вы правы. Вам нужно прочитать столько строк, сколько необходимо для архивирования строки, которую вы хотите прочитать.Сам файл не содержит метаданных (вспомогательных) -данных, которые могут помочь перейти непосредственно в нужную позицию. Если вы не собираете такие метаданные самостоятельно, подсчет строк при чтении является единственным способом. Существенным фактом является то, что использование _ignore_ вместо _getline_ намного более эффективно. –

+0

Отлично, он работает нормально. Спасибо за вашу помощь. – Mattia

1

Кажется, не существуют какие-либо конкретные функций C++, как «seekline», для ваших нужд, и я вижу два пути решения этой задачи:

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

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