我想从文件中读取 Unicode 文本行(UTF-16 LE,换行符分隔)。我正在使用 Visual Studio 2012 并针对 32 位控制台应用程序。
我无法在 WinAPI 中找到 ReadLine 函数,所以我求助于 Google。很明显,我不是第一个寻求这种功能的人。最普遍推荐的解决方案是使用 std::wifstream。
我编写了类似于以下的代码:
wchar_t buffer[1024];
std::wifstream input(L"input.txt");
while (input.good())
{
input::getline(buffer, 1024);
// ... do stuff...
}
input.close();
为了便于解释,假设 input.txt 包含两个长度小于 200 wchar_t 字符的 UTF-16 LE 行。
在第一次调用 getline 之前,Visual Studio 正确识别该缓冲区是 wchar_t 数组。您可以将鼠标悬停在调试器中的变量上,并看到该数组由 16 位值组成。但是,在 getline 调用返回后,调试器现在将缓冲区显示为字节数组。
在第一次调用 getline 之后,缓冲区的内容是正确的(除了缓冲区被视为字节数组)。如果 input.txt 的第一行包含 UTF-16 字符串 L“123”,则该字符串在缓冲区中正确存储为(十六进制)“31 00 32 00 33 00”
我的第一个想法是reinterpret_cast<wchar_t *>(buffer)
哪个确实产生了所需的结果(缓冲区现在被视为 wchar_t 数组)并且它包含我期望的值。
然而,在第二次调用 getline 之后,(input.txt 的第二行包含字符串 L“456”)缓冲区包含(十六进制)“00 34 00 35 00 36 00”。请注意,这是不正确的(应该是 [hex] 34 00 35 00 36 00)
字节顺序混乱的事实使我无法使用 reinterpret_cast 作为解决此问题的解决方案。更重要的是,为什么 std::wifstream::getline 甚至将我的 wchar_t 缓冲区转换为 char 缓冲区?我的印象是,如果有人想使用字符,他们会使用 ifstream,如果他们想使用 wchar_t,他们会使用 wifstream ...
我很难理解 stl 标头,但看起来 wifstream 似乎故意将我的 wchar_t 转换为 char ......为什么?
对于理解这些问题,我将不胜感激任何见解和解释。