2010-05-10 25 views
1

我的C++程序需要知道某个文本文件中有多少行。我可以用getline()和while循环来做,但是有更好的方法吗?使用C++找出文本文件中有多少行

+2

我认为'getline()'是要走的路 – knittl 2010-05-10 07:42:23

+0

你无法避免阅读整个文件。有一些不可移植的优化可能,这取决于平台,但getline()很好。 – peterchen 2010-05-10 08:38:40

+0

有趣的是我会比较我的猜测,特别是我想知道'ifstream'使用的缓冲策略:我认为较少的磁盘访问会更好,因此大块将是要走的路;但我不知道缓冲区有多大或者是否可以对其进行参数化。 – 2010-05-10 09:07:40

回答

4

不,除非你的操作系统的文件系统跟踪的行数,因为它是一个looong时间,因为我已经看到了,您的系统几乎可以肯定不会的。

+0

VMS是我所知道的唯一的操作系统是这样做的 - 它将文本文件的每一行视为“记录” – 2010-05-10 07:44:47

+0

我想知道某些文件系统是否真的这样做。很高兴知道。 – peterchen 2010-05-10 08:42:02

1

使用get()逐个字符地逐个字符的文件,并为每个换行符(\n)将行号加1。

+0

该方法比我刚才讨论的方法更糟糕。我试图避免读取整个文件。 – neuromancer 2010-05-10 07:41:34

+0

这是太慢了 – knittl 2010-05-10 07:41:58

+0

@ knittl:你怎么知道?曾听说过早优化? – 2010-05-10 07:45:32

2

通过“另一种方式”,你的意思是更快的方式?无论如何,您需要阅读文件的全部内容。由于操作系统或底层文件库(或两者)正在缓冲文件内容,因此读取不同大小的块应该无关紧要。

getline如果在非常大的文件中只有几行(高瞬态内存使用率),可能会出现问题,因此您可能需要读入固定大小的4KB块并逐个处理它们。

1

最快的,但依赖于操作系统的方法是将映射整个文件到内存(如果无法将整个文件一次地图 - 在顺序组块映射的话),并调用std::count(mem_map_begin,mem_map_end,'\n')

+0

哪些操作系统可以做到这一点? – neuromancer 2010-05-10 08:10:43

+0

最常见的链接: unix:http://linux.die.net/man/2/mmap windows:http://msdn.microsoft.com/en-us/library/aa366556(VS.85)。 aspx – catwalk 2010-05-10 08:25:03

+0

你为什么认为这比getline更快? – ChrisW 2010-05-10 08:40:34

0

不知道如果getline()是最好的 - 缓冲区大小在最坏情况下是可变的(\ n序列),它可以在每次迭代中读取字节后的字节。

对我来说,最好是以预定大小的块读取文件。而不是扫描一些新的行编码(内部) 尽管存在一些风险,我不能/不知道如何解决:其他文件编码不是ASCII。如果getline()处理的比最容易,但我不认为它是真的。

一些网址:

Why does wide file-stream in C++ narrow written data by default?

http://en.wikipedia.org/wiki/Newline

0

可能最快的方法是使用)低电平读取(扫描和缓冲区 '\ n' 的

int clines(const char* fname) 
{ 
    int nfd, nLen; 
    int count = 0; 
    char buf[BUFSIZ+1]; 

    if((nfd = open(fname, O_RDONLY)) < 0) { 
     return -1; 
    } 

    while((nLen = read(nfd, buf, BUFSIZ)) > 0) 
    { 
     char *p = buf; 
     int n = nLen; 
     while(n && (p = memchr(p,'\n', n))) { 
      p++; 
      n = nLen - (p - buf); 
      count++; 
     } 
    } 
    close(nfd); 
    return count; 
} 
相关问题