簡體   English   中英

向后讀取文件,c ++ ifstream

[英]Reading file backwards , c++ ifstream

我想向后讀一個文件 - 從結尾到開頭。 這有效,但不僅我想從文件中獲取字符,我想在閱讀時刪除它們。

std::fstream fileA;
fileA.seekg(-1, fileA.end);
int size = fileA.tellg();
for (i = 1; i <= size; i++)
{
    fileA.seekg(-i, fileA.end);
    fileA.get(ch);

    std::cout << ch;
}

無論如何要做到這一點,沒有復制內容和創建一個沒有我讀過的新文件?

如果不使用此處此處概述的方法之一,這是不可能的。 如果查看istream_iterator,您將看到它是一個輸入迭代器(24.6.1)(1)

類模板istream_iterator是一個輸入迭代器

然后從(24.2.1)(表105)

Random Access -> Bidirectional -> Forward -> Input
                                          -> Output

正如您所看到的,輸入迭代器是一個限制性更強的前向迭代器,而前向迭代器只能朝一個方向前進。 由於這種行為,它們不是在輸入流結束時開始並向后行走的標准方法

如果您只想以相反的順序呈現二進制數據,無論其含義如何,您的代碼都可以。

一些建議:

  • 然后,您應該打開binary流以獲得整個平台的一致性(即避免在平台上使用雙換行符轉換換行符,例如將其編碼為0x0d,0x0a窗口)。

  • 您還可以考慮在循環中使用與當前位置相對的位置,向后導航,而不是總是走到最后並從末尾的絕對位置重新設置自己。

這里是經過微調的代碼:

ifstream fileA("test.txt", ios::binary);  // binary data because binary revert
fileA.seekg(-1, ios::end); // position on last char to be read 
char ch; 
for (; fileA.get(ch); fileA.seekg(-2, ios::cur))  // try to read and rewind.  
    std::cout << ch;

但是,您的代碼無法讀取正確的UTF8編碼文件,因為多字節序列將受到機械上的尊重,並且它們的還原版本無效UTF8:

  • 如果您的文件中只有ASCII字符,則這不是問題。
  • 如果UTF8一致性對你來說是一個問題,你可以考慮一個非常簡單的解決方法 :如果你讀取一個字符u (u & 0xC0) == 0x80 ,你必須讀取所有前面的字符,直到這個條件變為false,並輸出正確順序的字節組(2到8之間)。

在這里怎么做:

...                           // If UTF-8 must be processed correctly
fileA.seekg(-1, ios::end);
char ch, buft[9]{},*p;
bool mb=false; 
for (; fileA.get(ch); fileA.seekg(-2, ios::cur))
{
    if (mb) {  // if we are already processing a multibyte sequence
        if ((ch & 0xC0) == 0x80 && p!=buft) // still another byte ?
            *--p=ch; 
        else {
            cout <<ch<<p;   // if no other output the current leading char followed by the multibyte encoding that we've identified
            mb=false;      // and multibyte processing is then finished
        }
    }
    else if ((ch & 0xC0) == 0x80) {  // if a new multibyte sequence is identified
        mb =true;      // start its processing
        buft[7]=ch; 
        p=buft+7; 
    }
    else std::cout << ch;  // normal chars ar procesed as before.
}

這是一個可運行的演示

最后一點:從輸入流中刪除最后一個字節取決於操作系統。 你應該看看這個問題,以獲得有關如何在linux / posix和windows上進行操作的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM