2014-06-19 35 views
1

我想使用C++訪問文本文件中的最後6行。任何人都可以提供一個代碼,在一段時間內到達那裏?提前致謝。 :)訪問文本文件中的最後6行C++

fstream myfile("test.txt"); 
myfile.seekg(-6,ios_base::end); 
string line; 
while(getline(myfile,line)) 
{ 
    if(vect.size() != VSIZE) 
    { 
     vect.push_back(line); 
    } 
    else 
    { 
     vect.erase(v.begin()); 
     vect.push_back(line); 
    } 
} 

它似乎不工作...和VSIZE是6 ...請爲我提供幫助和工作代碼。

+1

'seekg(-6)'獲取文件的最後6個字符,而不是最後6行。 – Barmar

+1

逐行讀取文件,將行放入矢量中。當矢量有6行時,在添加新行之前刪除第一行。 – Barmar

+0

我實際上在做同樣的事情。但爲此我必須從頭閱讀整個文件。我需要一個代碼,可以將我帶到最後6行的前面,而不是線性時間。 –

回答

0

這是一件相當困難的事情,有幾個邊緣案例需要考慮。

廣義的策略是:

  1. 以二進制方式打開文件,所以你看到的每一個字節。
  2. 尋找到(end - N),其中N是任意緩衝區的大小。大約1K應該這樣做。
  3. 將N個字節讀入緩衝區。向後掃描尋找LF字符('\ n)。如果有的話跳過最後一個。
  4. 每行都在LF後開始,所以向後計數直到達到6.
  5. 如果找不到6,則向後尋找另外N個字節,讀取另一個緩衝區並繼續掃描。
  6. 如果您到達文件的開頭處,請停止。

我把代碼留作練習。

+0

我如何從當前位置向後掃描文件?你能爲我解釋一下嗎? –

+0

你不會倒退。您尋求(結束 - N),然後向前讀取N個字節。 –

2

這條線:

myfile.seekg(-6,ios_base::end); 

尋求到6個字節的文件,而不是6號線年底前。您需要向後計算換行或從頭開始。所以如果你刪除上面的行,你的代碼應該可以工作。

+0

是的我的代碼通過刪除該行來工作。但每次只是爲了訪問最後幾行我正在閱讀整個文件。我如何把它帶到一定的時間? –

0

This答案解釋了爲什麼你做什麼都行不通。下面我解釋一下會起什麼作用。

  1. 以二進制模式打開文件。
  2. 從頭開始在長度爲6的循環緩衝區中存儲'\ n'的位置。(boost :: circular_buffer可以幫助)
  3. 從環形緩衝區中的最小位置開始轉儲文件的內容。

第2步可以通過尋找結束X來改進,其中X是由文件尾部周圍的某種二等分派生的。

0

可能最簡單的方法就是將mmap()這個文件。這會將其內容放入虛擬地址空間,因此您可以輕鬆地從頭到尾對前六行結束進行掃描。

由於映射文件給你一個單一的大緩衝區內存在整個文件的錯覺,而實際上並沒有加載你不需要的部分,它既可以避免不必要的I/O,也可以減少管理增長當你向後搜索行結束符時使用緩衝區。