如果您只是想将二进制数据以相反顺序呈现,无论其含义如何,您的代码都可以。
一些建议:
你应该再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编码的文件,因为多字节序列将被mecanically revereted,他们恢复的版本是无效的UTF8 :
- 如果您的文件中只有ASCII码字符,这不是问题。
- 如果UTF8一致性对于你的问题,你可以考虑一个非常简单的解决方法:如果你读了这
(u & 0xC0) == 0x80
字符u
,你必须直到这个条件变为假读取所有前面的字符,并且输出组字节(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.
}
这里一个runnable demo。
最后一点:从输入流中移除最后一个字节取决于操作系统。你应该看看this SO question以获得如何在linux/posix和windows上执行它的答案。
“这工作”:我想知道你是否试过一个utf8文件 – Christophe
记事本说它是UTF 8没有BOM。那很重要吗?代码适用于阅读... @Christophe – Noam
您的方法中存在的问题是多字节UTF8字符。我们以小pi为例:它的UTF8编码是0xCF 0x80。如果您在输出0x80 0xCF中写入,则这是一个无效的UTF8序列。但是,在任何文本的windows下都会出现同样的问题:'\ n'在文件中编码为0x0D 0x0A。在文本模式下阅读时,只有在阅读该序列时才会得到'\ n'。但是用你的方法,你将首先定位在0x0A上,然后你将得到'\ n',然后你将定位在0x0D上,这将再次被读作'\ n'(因为它后面跟着0x0A)。所以你会把每一条新线都加倍。 – Christophe