2

访问文本文件时,我想从特定行读取。假设我的文件有 1000 行,我想读取第 330 行。每行有不同数量的字符,并且可能很长(假设每行大约 100,000,000 个字符)。我想fseek()不能在这里有效地使用。

我正在考虑一个循环来跟踪换行符,但我不知道如何实现它,也不知道这是否是最好的解决方案。

你能提供任何帮助吗?

4

5 回答 5

3

除非您在文件中有某种索引说“行 M 从位置 N 开始”,否则您必须从文件中读取字符并计算换行符,直到找到所需的行。

std::getline如果您想保存每行的内容,或者std::istream::ignore如果您想丢弃您阅读的行的内容,直到找到所需的行,您可以轻松地阅读行。

于 2011-02-07T15:53:10.047 回答
2

如果不扫描整个文件,找到换行符,然后计数,就无法知道任意文本文件中第 330 行的开始位置。

如果您只需要这样做一次,请扫描。如果你需要做很多次,那么你可以扫描一次,并在所有行开始的地方建立一个数据结构列表。现在你可以弄清楚在哪里阅读该行。如果您仍然只是在考虑如何组织数据,我建议您使用其他类型的数据结构进行随机访问。在不知道您要解决的实际问题的情况下,我无法推荐哪一个。

于 2011-02-07T15:52:55.677 回答
1

在文件上创建索引。您可以“懒惰地”执行此操作,但当您读取缓冲区已满时,您不妨扫描每个字符。

如果它是 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 在哪里。

于 2011-02-07T15:59:00.740 回答
1

我认为您需要扫描文件并计算 \n 的出现次数,因为您找到了所需的行。如果这是一个频繁的操作,并且您是唯一一个编写文件的人,您可能会同时维护一个包含此类信息的索引文件和包含数据的索引文件,一种“可怜的人索引”,但是可以节省很多时间。

于 2011-02-07T15:52:05.163 回答
0

尝试循环运行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;
}
于 2011-02-07T15:58:29.743 回答