前几天,我正在编写类似于以下内容的代码:
wchar_t buffer[1024];
std::wifstream input(L"input.txt");
while (input.good())
{
input::getline(buffer, 1024);
// ... do stuff...
}
input.close();
我发现,在第一次调用 之后getline
,buffer
它包含正确的数据(UTF-16 LE)字节,但它没有buffer
被视为 wchar_t 数组,而是神奇地转换为字节数组。我reinterpret_cast<wchar_t *>(buffer)
得到了我想要的结果。
然后下一次调用getline
... 这次,缓冲区再次被视为一个字节数组,但字节是倾斜的。我期待看到0x31 0x00 0x32 0x00 0x33 0x00
,但我看到了0x00 0x31 0x00 0x32 0x00 0x33
现在,我可以理解如果字符具有可变长度编码,事情可能会如何扭曲......但是我的 input.txt 文件中的所有字符都是 ASCII,因此每个字符都可以用 2 个字节编码(使用 UTF16-LE)。为什么偏斜?
SO 上的一位回答者告诉我,我应该像这样灌输流:
std::wifstream fin("text.txt", std::ios::binary);
// apply facet
fin.imbue(std::locale(fin.getloc(),
new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));
确实,这完全解决了我的问题。如果您正在处理的所有字符都具有固定长度的编码,我不明白为什么需要注入?
其次,灌输的第二个参数似乎是内存泄漏?!如果我在堆栈上分配一个std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>
对象并将其地址传递给 imbue,那么一切似乎都可以工作,直到我的堆栈变量超出范围(就在主右括号之前)。应用程序崩溃,抱怨某些函数正在调用纯虚函数。如果我使用提供的代码并在 main 返回之前在内存上调用 delete,我会看到相同的行为。
提前感谢您的评论和回答。