人们建议使用many examples类似的技巧来获取Unicode控制台输出:
begin
OldConsoleOutputCP := GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
try
// Might also use WriteConsoleA, but this has drawbacks with output redirection
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), Utf8Bytes, ...);
finally
// We better restore the output CP that was in use before our program started!
SetConsoleOutputCP(OldConsoleOutputCP);
end;
end.
这似乎工作得很好。
MSDN文档only ever mentions(至少据我所知),您should use
WriteConsoleW
用于控制台输出,而WriteFile
用于重定向输出。 (您可以通过GetConsoleMode
的返回值和类似方法来检测该句柄是否为控制台句柄)。Microsoft正式支持使用
SetConsoleOutputCP(CP_UT8)
将Unicode文本输出到控制台并重定向输出吗?如果是,在哪里记录?我以为UTF-8多字节代码页应该只用于
WideCharToMultiByte
和MultiByteToWideChar
函数? 最佳答案
Microsoft是否正式支持使用SetConsoleOutputCP(CP_UT8)将Unicode文本输出到控制台并重定向输出?
当然,它并没有明确得到支持,但是在这里很难说什么算是“受支持的”,这是一个文档非常缺乏的领域。
在实践中,当控制台在另一端且其代码页设置为65001时,I / O就有严重的错误,包括WriteFile
。通常,Win32 I / O API(和MSVCRT stdlib例程构建在顶部)错误),因为它返回的实际上是字符数的字节写入或读取计数失败。
在您的示例中这并不重要,因为您忽略了lpNumberOfBytesWritten
的WriteFile
外部参数,但是通常当您使用非ASCII字符时,错误的计数将导致重复输出混乱,并在尝试更多数据时挂起等待读取输入。
这是控制台(主机)中的错误:它具有特殊情况支持,可将双字节字符集的代码页的正确计数传回Windows,这些代码页用作任何安装区域设置的默认代码页(“非Unicode应用程序”),但不适用于其他通用多字节编码。
由于@IInspectable的linked,至少Microsoft的一部分明确拒绝解决此问题的一个明显方面,尽管不是根本原因的Microsoft。不管怎样,不幸的是,这个长期存在且令人深感沮丧的问题似乎不会很快结束。
//可能也使用WriteConsoleA,但这在输出重定向方面有缺点
是的,一种常见的方法是检测stdout是否是您自己的控制台(例如,使用_isatty
)并在这种情况下转移到WriteConsoleW
。