2016-08-04 43 views
0
// Print the last n lines of a file i.e implement your own tail command 
#include <iostream> 
#include <fstream> 
#include <string> 
int main() 
{ 
    std::ifstream rd("D:\\BigFile.txt"); 
    int cnt = 0;char c; 
    std::string data; 
    rd.seekg(0,rd.end); 
    int pos=rd.tellg(); 

    while(1) 
    { 

    rd.seekg(--pos,std::ios_base::beg); 

     rd.get(c); 
     if(c=='\n') 
     { 
      cnt++; 
     // std::cout<<pos<<"\t"<<rd.tellg()<<"\n"; 

     } 

     if(cnt==10) 
     break; 

} 
     rd.seekg(pos+1); 
     while(std::getline(rd,data)) 
    { 
     std::cout<<data<<"\n"; 
    } 



    } 

所以,我寫這個程序打印文本文件的最後10行。然而,它僅打印最後5個,由於某種原因,每次遇到實際的'\ n'時,下一個get()也會導致\ n導致錯誤的輸出。這裏是我的輸入文件:get()(從C++中的文件讀取)的不尋常的行爲

Hello 
Trello 
Capello 
Morsello 
Odello 
Othello 
HelloTrello 
sdasd 
qerrttt 
mkoilll 
qwertyfe 

我使用Windows記事本,這是我的輸出:

HelloTrello 
sdasd 
qerrttt 
mkoilll 
qwertyfe 

我無法弄清楚爲什麼發生這種情況,請幫助。

+0

我會給出一個猜測(儘管我不確定)'get'將'\ n'和'\ r'讀爲'\ n'。在我的電腦上,使用'\ n'作爲行結束符,使用g ++編譯。 – elyashiv

+0

在文本文件流上的** only **安全查找要麼是'0',要麼是之前調用'tellg'返回的值,您正在'pos'中搞亂,然後尋找哪一個是技術上未定義的行爲。爲什麼不給'std :: vector '緩衝n行,循環遍歷文件,用'getline'替換舊行,然後轉儲文件完成時留下的內容? – user657267

回答

3

如果在文本模式下打開文件,請不要對文件位置使用算術運算。它不會給你正確的結果。

如果在文本模式下打開文件,則1個字符並不總是表示1個字節。以及如何實現文件位置(如果它指向特定的字符或字節)未指定。

在你的情況下,問題是在Windows上換行符號是兩個字節長。文本流將其轉換爲單字節符號'\n',因此您不必擔心平臺與實際使用的字節序列之間的差異。

因此,您的第一次讀取會讀取ASCII字符中與'\n'值相同的雙字節結束符號的最後一個字節。接下來在兩字節結束符號開始處讀取土地,並將其正確地轉換爲'\n'