C++ 向后读取文件,c++;文件流

C++ 向后读取文件,c++;文件流,c++,fstream,C++,Fstream,我想从一个文件中倒读——从结尾到开头。 这是可行的,但我不仅希望从文件中获取字符,还希望在阅读时删除它们 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; } std::fst

我想从一个文件中倒读——从结尾到开头。 这是可行的,但我不仅希望从文件中获取字符,还希望在阅读时删除它们

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;
}
std::fstream文件a;
文件a.seekg(-1,文件a.end);
int size=fileA.tellg();

对于(i=1;i如果您只想以相反的顺序获取二进制数据,那么无论其含义如何,您的代码都可以

一些建议:

  • 然后,应在
    二进制
    中打开流,以确保跨平台的一致性(即,避免在诸如windows之类的平台上将换行符转换为双换行符,这些平台将其编码为
    0x0d,0x0a

  • >P>你也可以考虑在循环中使用相对位置到当前位置,向后导航,而不是一直走到末端,并将自己从末尾的绝对位置重新赋值。

这里是经过微调的代码:

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;
这里有一个


最后一点:从输入流中删除最后一个字节取决于操作系统。您应该了解如何在linux/posix和windows上执行此操作。

如果不使用上述方法之一或,这确实是不可能的。如果查看istream_迭代器,您将看到它是一个输入迭代器(24.6.1)(1)

类模板istream_迭代器是一个输入迭代器

然后从(24.2.1)开始(表105)


正如您所见,输入迭代器是一种限制性更强的前向迭代器,前向迭代器只能朝一个方向运行。由于这种行为,它不是从输入流末尾开始并向后走的标准方式:我想知道你是否试过utf8文件。记事本上说它是utf8格式的,没有BOM表。这有关系吗?代码用于读取…@Christophen方法中的问题是多字节utf8字符。让我们以小pi为例:它的utf8编码是0xCF 0x80。如果你在输出0x80 0xCF中写入,则它是无效的utf8序列。但在windows下,对于任何文本都会出现相同的问题:“\n”在文件中编码为0x0D 0x0A。在文本模式下读取时,您只能在读取此序列时获得“\n”。但是,使用您的方法,您将首先在0x0A上定位,然后在0x0D上定位,这将再次被读取为“\n”(因为后面跟着0x0A)。所以你会把每一行换行都加倍。你看过了吗?@Christophe:这对于UTF-8或UTF-16来说是很容易解决的——你可以从这个值看出0x80是多字节序列的一部分,并且你可以知道何时到达第一个字节。但是,当你读一段代码时,处理组合变音符号要困难得多点,除了阅读前面的代码点之外,你不知道它前面是否可能有一个组合变音符号。没有标准的迭代器可以做到这一点并不意味着没有标准的方法可以做到这一点。仍然对两个链接的问题/答案投赞成票。特别是
mmap()
方法值得考虑。
...                           // 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.
}
Random Access -> Bidirectional -> Forward -> Input
                                          -> Output