Delphi CP_UTF8是WriteConsoleA/WriteFile支持的代码页吗?
有人建议使用类似的技巧获得Unicode控制台输出:Delphi CP_UTF8是WriteConsoleA/WriteFile支持的代码页吗?,delphi,winapi,unicode,console,delphi-xe7,Delphi,Winapi,Unicode,Console,Delphi Xe7,有人建议使用类似的技巧获得Unicode控制台输出: 开始 OldConsoleOutputCP:=GetConsoleOutputCP(); 设置控制台输出CP(CP_UTF8); 尝试 //也可以使用WriteConsoleA,但这在输出重定向方面有缺点 WriteFile(GetStdHandle(标准输出句柄),Utf8Bytes,…); 最后 //我们最好恢复程序启动前使用的输出CP! 设置控制台输出端口CP(旧控制台输出端口CP); 结束; 结束。 这似乎很有效 MSDN文档(至少
开始
OldConsoleOutputCP:=GetConsoleOutputCP();
设置控制台输出CP(CP_UTF8);
尝试
//也可以使用WriteConsoleA,但这在输出重定向方面有缺点
WriteFile(GetStdHandle(标准输出句柄),Utf8Bytes,…);
最后
//我们最好恢复程序启动前使用的输出CP!
设置控制台输出端口CP(旧控制台输出端口CP);
结束;
结束。
这似乎很有效
MSDN文档(至少据我所知)用于控制台输出的是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例程)会返回实际为字符数的写入或读取字节数,从而导致失败
在您的示例中,这并不重要,因为您忽略了WriteFile
的LPNumberOfBytesWrited
输出参数,但通常当您使用非ASCII字符时,错误的计数将导致重复输出损坏,并在尝试读取输入时挂起等待更多数据
这是控制台(conhost)中的一个错误:它具有特殊案例支持,可以将双字节字符集代码页的正确计数传递回Windows,这些双字节字符集代码页用作任何安装区域设置(“非Unicode应用程序的语言”)的默认代码页,但不用于其他通用多字节编码
正如@IInspectable所说,微软至少有一部分人明确拒绝修复这个问题的一个明显方面,尽管不是微软的一部分人拥有这个问题的根本原因。不管怎样,遗憾的是,这个长期存在且令人沮丧的问题似乎不会很快结束
//也可以使用WriteConsoleA,但这在输出重定向方面有缺点
是的,一种常见的方法是自己检测stdout是否是控制台(例如使用
\u isatty
),并在这种情况下分支到WriteConsoleW
。值得一提的是,文档中列出的注册表项在我的系统上不包含65001(CP\u UTF8
)。因为你会看到程序/库行为不端。此外,还有一些API(如IsDBCSLeadByte
)本质上与UTF-8不兼容。