请考虑以下代码片段,在MS Visual Studio 2010/2012上编译为控制台应用程序并在Win7上执行:
#include "stdafx.h"
#include <iostream>
#include <string>
const std::wstring test = L"hello\xf021test!";
int _tmain(int argc, _TCHAR* argv[])
{
std::wcout << test << std::endl;
std::wcout << L"This doesn't print either" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一个wcout语句输出"hello"(而不是"hello?test!")第二个wcout语句输出什么.
就像0xf021(和其他?)Unicode字符导致wcout失败一样.
这个特殊的Unicode字符0xf021(编码为UTF-16)是Basic Multilingual Plane中"Private Use Area"的一部分.我注意到Windows控制台应用程序没有对Unicode字符的广泛支持,但通常每个字符至少由默认字符(例如"?")表示,即使不支持呈现特定字形.
是什么导致wcout流窒息?有没有办法在它进入这种状态后重置它?
多年来我在C和C++中多次写过这样的无限循环,但今天是我第一次真正想到它 - 为什么条件子句为空时它是一个无限循环?人们会期望你必须写一些类似于for(;true;);获得有效无限循环的东西?
while(); 不编译也不编译 while(;);
无论如何,我喜欢for(;;);语法并经常使用它,但是将空条件块视为true是特殊情况还是在C或C++中有其他情况将空条件表达式解释为true?
我想从文件中读取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();
Run Code Online (Sandbox Code Playgroud)
为了便于说明,假设input.txt包含两条UTF-16 LE线,其长度小于200个wchar_t个字符.
在第一次调用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")缓冲区包含(hex)"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 ...为什么?
我将不胜感激任何理解这些问题的见解和解释.