Доступ к информации в файле ".txt" и переход к определенной строке - PullRequest
2 голосов
/ 07 февраля 2011

При доступе к текстовому файлу я хочу прочитать из определенной строки.Давайте предположим, что мой файл имеет 1000 строк, и я хочу прочитать строку 330. Каждая строка имеет различное количество символов и может быть довольно длинной (скажем, около 100 000 000 символов в строке).Я думаю, fseek() не может быть эффективно использован здесь.

Я думал о цикле для отслеживания разрывов строк, но я не знаю, как именно это реализовать, и я не знаюесли это будет лучшим решением.

Можете ли вы предложить какую-либо помощь?

Ответы [ 5 ]

3 голосов
/ 07 февраля 2011

Если у вас нет какого-либо индекса, говорящего "строка M начинается с позиции N" в файле, вы должны читать символы из файла и считать новые строки, пока не найдете нужную строку.

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

2 голосов
/ 07 февраля 2011

Невозможно узнать, где начинается строка 330 в произвольном текстовом файле, не сканируя весь файл, не находя разрывы строк и не считая их.

Если вам нужно сделать это только один раз, то сканируйте,Если вам нужно сделать это много раз, то вы можете отсканировать один раз и создать список структур данных, с которого начинаются все строки.Теперь вы можете выяснить, где искать, чтобы прочитать только эту строку.Если вы все еще думаете о том, как организовать данные, я бы предложил использовать другой тип структуры данных для произвольного доступа.Я не могу рекомендовать какой, не зная фактическую проблему, которую вы пытаетесь решить.

1 голос
/ 07 февраля 2011

Создать индекс для файла. Вы можете сделать это «лениво», но, читая буфер, вы можете также сканировать его для каждого символа.

Если в Windows это текстовый файл, в котором используется 2-байтовый символ '\ n', то число символов, которые вы прочитали до точки, где начинается символ новой строки, не будет смещением. Так что вы должны делать поиск после каждого вызова getline ().

что-то вроде:

std::vector< off_t > lineNumbers;
std::string line;
lineNumbers.push_back(0); // first line begins at 0
while( std::getline( ifs, line ) )
{
   lineNumbers.push_back(ifs.tellg());
}

последнее значение скажет вам, где находится EOF.

1 голос
/ 07 февраля 2011

Я думаю, вам нужно отсканировать файл и сосчитать \ n вхождений, поскольку вы найдете нужную строку. Если это частая операция, и вы единственный, кто пишет файл, вы можете поддерживать индексный файл, содержащий такую ​​информацию, рядом с файлом, содержащим данные, что-то вроде «плохого индекса», но может сэкономить много времени.

0 голосов
/ 07 февраля 2011

Попробуйте запустить fgets в цикле

/* fgets example */
#include <stdio.h>

int main()
{
   FILE * pFile;
   char mystring [100];

   pFile = fopen ("myfile.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fgets (mystring , 100 , pFile);
     puts (mystring);
     fclose (pFile);
   }
   return 0;
}
...