2010-05-10 64 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; 
} 
相關問題