【发布时间】:2015-08-22 22:01:39
【问题描述】:
尝试在 Delphi XE7 控制台应用程序中显示 UTF 8 文本时,我遇到了一个愚蠢但令人讨厌的情况。 似乎 ReadLn 命令在第二次尝试后才读取正确的 UTF 8 字符。例如:
program ConsTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes,
WinApi.Windows;
var
CurrentCodePage: Integer;
Command: String;
Running: Boolean;
MyText: String;
begin
CurrentCodePage := GetConsoleOutputCP;
SetConsoleOutputCP(CP_UTF8);
SetTextCodePage(Output, CP_UTF8);
MyText := 'Olá mundo.';
WriteLn(MyText);
Running := True;
while Running do
begin
ReadLn(Command);
WriteLn(Command);
if (Command = '/q') then
Running := false;
end;
SetConsoleOutputCP(CurrentCodePage);
SetTextCodePage(Output, CurrentCodePage);
end.
在上面的示例中,在我运行应用程序之后,如果我输入以下文本:
'Olá mundo.'
WriteLn 将显示:
'老世界。'
在第一遍之后,ReadLn 命令读取的所有 UTF-8 字符都显示正常。 这段代码有问题吗?我试图在网上搜索更多细节,但我没有找到任何与此相关的信息。 调用“WriteLn(MyText);”在代码的开头,显示文本“Olá mundo”。正确。
【问题讨论】:
-
在将 windows 控制台切换为 UTF8 后,您可以关闭并重置输入文件吗?读/写有自己的内部缓冲区,在切换代码页之前可能会预先填充并预先转换为 UCS-2
-
我也认为
SetTextCodePage应该在Input和Output上调用,实际上这可能比CloseFile/Reset优于Input更好或更糟 -
我认为@TLama 指向
SetConcoleCP函数msdn.microsoft.com/ru-ru/library/windows/desktop/ms686013.aspx 是正确的-但是它是否适用于UTF-8 以及哪些Windows 版本需要反复试验:@987654323 @ OTOH 有 MSYS、4NT/TakeW32、Cygwin 等替代控制台,也许还有 PowerShell... -
@Arioch 使用与示例相同的代码,如果我尝试您建议的测试(如果 MyText=Command 然后 writeln ('yes') else writeln('no');)。它在第一遍评估为假,在所有后续遍中评估为真。如果我将输入代码页更改为 UTF8,它总是会失败。
标签: delphi utf-8 console console-application windows-console