c++ - 这个 UTF-8 格式的 BOM 不正确吗?
问题描述
我想在 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 本身没问题。您只是错误地打印出字节。
您看到的结果是由于将有符号8 位值符号扩展char
为有符号 32 位整数。char
是有符号还是无符号是编译器定义的,除非您在代码中明确声明。在您的情况下,您正在使用(隐式) signed char
。有符号char
值 > 127 将其高位设置为 1,当将有符号 8 位值扩展为有符号 32 位值时,它将用 1 填充新位。
要正确输出字节,您需要将值进行零扩展,而不是符号扩展。为此使用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;
}
}
推荐阅读
- node.js - 多个访客请求存在问题
- api - Travis CI - 是否可以在 Travis CI 上使用 2 个存储库进行构建?
- angular - 使用异步管道的 Material Stepper 动态初始化
- java - JAR 作为应用程序安装时未生成应用程序日志
- spring-boot - 简单的网络 CRUD WebFlux 应用程序:Netty 有什么用处?
- python-3.x - 无法从 Tkinter 拉取上传加载的数据
- android - 版本控制中的 Android 调试密钥库
- php - 协助 RegexIterator 和文件过滤
- groovy - Groovy - 2个月之间的差异
- reactjs - react-grid layout html不更新cols