Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi CP_UTF8是WriteConsoleA/WriteFile支持的代码页吗?_Delphi_Winapi_Unicode_Console_Delphi Xe7 - Fatal编程技术网

Delphi CP_UTF8是WriteConsoleA/WriteFile支持的代码页吗?

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文档(至少

有人建议使用类似的技巧获得Unicode控制台输出:

开始
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不兼容。