为什么std::wistream的read()和get()方法读取单字节宽度字符?
为什么std::wifstream读取BOM仅返回1字节
你遇到的问题本质是对std::wifstream的设计定位理解有误,核心原因如下:
std::wifstream是带编码转换的文本流,不是原始二进制流,不会直接按wchar_t的内存大小读取字节。它的所有读取操作都会先通过当前locale绑定的std::codecvt转换 facet,把底层读取的字节序列按编码规则转换为宽字符,读取的字节数完全由编码规则决定,和wchar_t本身占多少字节没有关系。- 大部分环境下C++标准流默认使用
Clocale,对应的是单字节的ASCII兼容编码(如ISO-8859-1),该编码规则下每个字节对应一个宽字符,因此调用str.get(bom)时只会读取1个底层字节,转换为wchar_t类型后返回,自然只能拿到第一个0xFF字节。 - 你假设
wchar_t固定占2字节本身就是不严谨的:Windows平台下wchar_t为2字节存储UTF-16编码,但Linux、macOS等类Unix平台下wchar_t通常为4字节存储UTF-32编码,不存在跨平台统一的2字节规则。
如果要实现BOM检测,正确的做法是先用
std::ifstream读取文件开头的2~4个原始字节判断BOM类型,再根据BOM结果给宽字符流设置对应的编码locale即可。
内容的提问来源于stack exchange,提问作者Serge Roussak
相关产品推荐
相关产品推荐

