这个 UTF-8 格式的 BOM 不正确吗?
Is this BOM in UTF-8 incorrect?
想验证UTF-8的BOM,写了下面的c++代码
然而,结果是0XFFFFFFEF, 0XFFFFFFBB, 0XFFFFFFBF.
这与我预期的不同 0XEF, 0XBB, 0XBF.
为什么会变成上面的结果?
顺便说一句,使用的UTF-8文件是Notepad++制作的
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char file[]="/*UTF-8 file*/";
char a[3]{};
ifstream ifs(file, ios_base::binary);
ifs.read(a, static_cast<streamsize>(sizeof(a)));
cout << showbase << uppercase;
for(int i:a){
cout << hex << i << endl;
}
}
环境
海湾合作委员会 9.2.0
编译选项:-std=c++2a
BOM本身没问题。您只是错误地打印出字节。
您看到的结果是由于 sign extending 带符号的 8 位 char
值变成带符号的 32 位整数。 char
是 signed 还是 unsigned 是 compiler-defined,除非你在代码中明确声明。在您的情况下,您正在使用(隐式)签名 char
。有符号的 char
值 > 127 将其高位设置为 1,这将在将有符号的 8 位值扩展为有符号的 32 位值时用 1 填充新位。
要正确输出字节,您需要将值设置为 zero-extended,而不是 sign-extended。为此使用 unsigned
类型,例如:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char file[] = "/*UTF-8 file*/";
unsigned char a[3];
ifstream ifs(file, ios_base::binary);
ifs.read(reinterpret_cast<char*>(a), sizeof(a));
cout << showbase << uppercase;
for(unsigned int i : a){
cout << hex << setw(2) << setfill(‘0’) << i << endl;
}
}
想验证UTF-8的BOM,写了下面的c++代码
然而,结果是0XFFFFFFEF, 0XFFFFFFBB, 0XFFFFFFBF.
这与我预期的不同 0XEF, 0XBB, 0XBF.
为什么会变成上面的结果?
顺便说一句,使用的UTF-8文件是Notepad++制作的
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char file[]="/*UTF-8 file*/";
char a[3]{};
ifstream ifs(file, ios_base::binary);
ifs.read(a, static_cast<streamsize>(sizeof(a)));
cout << showbase << uppercase;
for(int i:a){
cout << hex << i << endl;
}
}
环境
海湾合作委员会 9.2.0
编译选项:-std=c++2a
BOM本身没问题。您只是错误地打印出字节。
您看到的结果是由于 sign extending 带符号的 8 位 char
值变成带符号的 32 位整数。 char
是 signed 还是 unsigned 是 compiler-defined,除非你在代码中明确声明。在您的情况下,您正在使用(隐式)签名 char
。有符号的 char
值 > 127 将其高位设置为 1,这将在将有符号的 8 位值扩展为有符号的 32 位值时用 1 填充新位。
要正确输出字节,您需要将值设置为 zero-extended,而不是 sign-extended。为此使用 unsigned
类型,例如:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char file[] = "/*UTF-8 file*/";
unsigned char a[3];
ifstream ifs(file, ios_base::binary);
ifs.read(reinterpret_cast<char*>(a), sizeof(a));
cout << showbase << uppercase;
for(unsigned int i : a){
cout << hex << setw(2) << setfill(‘0’) << i << endl;
}
}