提问人:Serge Roussak 提问时间:10/5/2021 更新时间:10/5/2021 访问量:160
为什么 std::wistream 读取字节宽度字符的 read() 和 get() 方法?
Why the read() and the get() methods of the std::wistream read byte-width character?
问:
我正在尝试获取文件开头是否具有Unicode BOM。我更喜欢使用标准库。我尝试按如下方式解决此任务:iostream
std::wifstream str(filename);
wchar_t bom;
str.get(bom);
我假设由于字符有两个字节大小,此代码应该从文件中读取前两个字节,但它只读取第一个字节。wchar_t
0xFF
我知道,这可以通过“普通”流来解决,但我有学术兴趣:为什么给定的代码只返回一个字节?
答:
1赞
n. m. could be an AI
10/5/2021
#1
basic_istream::get
尝试从流中读取一个字符,并将其转换为模板化的任何类型。basic_istream
构成流中的字符(流的字符编码)的内容由区域设置决定,而不是由模板化的类型决定。basic_istream
因此,如果需要强制实施 16 位字符编码,则需要在流中为 C++ 区域设置注入 16 位字符编码,而不管它是 还是 .据我所知,Windows 中没有内置的 16 位语言环境。您可以通过添加分面从系统提供的区域设置构造此类 C++ 区域设置,例如:ifstream
wifstream
codecvt
std::wifstream str(filename);
str.imbue(std::locale(str.getloc(),
new std::codecvt_utf16<wchar_t, 0x10ffff,
std::codecvt_mode::little_endian>));
如果您的编码是大端序,请跳过。也可以使用 跳过 BOM。std::codecvt_mode::little_endian
std::codecvt_mode::consume_header
std::codecvt_utf16
自 C++17 起已弃用,因此如果您决定使用它,则只能靠自己。您还可以构建自己的分面。codecvt
评论
0赞
Serge Roussak
10/5/2021
我知道 ,我已经使用它了。但你回答了另一个问题,不是我的。std::codecvt
0赞
n. m. could be an AI
10/5/2021
添加了与您的问题相关的信息。
评论