人们建议使用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多字节代码页应该只用于WideCharToMultiByteMultiByteToWideChar函数?

最佳答案

Microsoft是否正式支持使用SetConsoleOutputCP(CP_UT8)将Unicode文本输出到控制台并重定向输出?


当然,它并没有明确得到支持,但是在这里很难说什么算是“受支持的”,这是一个文档非常缺乏的领域。

在实践中,当控制台在另一端且其代码页设置为65001时,I / O就有严重的错误,包括WriteFile。通常,Win32 I / O API(和MSVCRT stdlib例程构建在顶部)错误),因为它返回的实际上是字符数的字节写入或读取计数失败。

在您的示例中这并不重要,因为您忽略了lpNumberOfBytesWrittenWriteFile外部参数,但是通常当您使用非ASCII字符时,错误的计数将导致重复输出混乱,并在尝试更多数据时挂起等待读取输入。

这是控制台(主机)中的错误:它具有特殊情况支持,可将双字节字符集的代码页的正确计数传回Windows,这些代码页用作任何安装区域设置的默认代码页(“非Unicode应用程序”),但不适用于其他通用多字节编码。

由于@IInspectable的linked,至少Microsoft的一部分明确拒绝解决此问题的一个明显方面,尽管不是根本原因的Microsoft。不管怎样,不幸的是,这个长期存在且令人深感沮丧的问题似乎不会很快结束。


//可能也使用WriteConsoleA,但这在输出重定向方面有缺点


是的,一种常见的方法是检测stdout是否是您自己的控制台(例如,使用_isatty)并在这种情况下转移到WriteConsoleW

08-16 04:46