Writeln能否支持Unicode? [英] Is Writeln capable of supporting Unicode?

查看:196
本文介绍了Writeln能否支持Unicode?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个程序:

  {$ APPTYPE CONSOLE} 

begin
Writeln ('АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ');
结束。

我使用Consolas字体的控制台上的输出是:

 
Z ???? ???

Windows控制台非常有能力支持Unicode,这个程序证明了这一点:

  {$ APPTYPE CONSOLE} 

使用
Winapi.Windows;

const
Text ='АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ';

var
NumWritten:DWORD;

begin
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),PChar(Text),Length(Text),NumWritten,nil);
结束。

输出为:

 
АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ

可以 Writeln 被说服遵守Unicode或者是固有的瘫痪?

解决方案

只需将控制台输出代码页设置为 SetConsoleOutputCP()例程与代码页 cp_UTF8

 程序Project1 ; 

{$ APPTYPE CONSOLE}

使用
System.SysUtils,Windows;
Const
Text ='АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ';
VAR
NumWritten:DWORD;
begin
ReadLn; //确保选择Consolas字体
try
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),PChar(Text),Length(Text),NumWritten,nil);
SetConsoleOutputCP(CP_UTF8);
WriteLn;
WriteLn('АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ');
除了
在E:Exception do
Writeln(E.ClassName,':',E.Message);
结束
ReadLn;
结束。

输出:

 code>АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾѾЩЪЫѢѤѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴЅѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴѦѪѨѬѠѺѮѰѲѴ>>>>>>>>>>>>>>>>>>>>>>>>>>>> / code>将Unicode UTF16字符串转换为内部选定的输出代码页(cp_UTF8)。






更新: p>

以上工作在Delphi-XE2及以上版本。
在Delphi-XE中,您需要明确转换为UTF-8才能使其正常工作。

  WriteLn(UTF8String ('АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ')); 






附录: / p>

如果在调用 SetConsoleOutputCP(cp_UTF8)之前,在另一个代码页中输入到控制台,则
操作系统将无法在 utf-8 中正确输出文本。
这可以通过关闭/重新打开stdout处理程序来修复。



另一个选项是为 utf-8 声明一个新的文本输出处理程序。

  var 
toutUTF8:TextFile;
...
SetConsoleOutputCP(CP_UTF8);
AssignFile(toutUTF8,'',cp_UTF8); //在XE2及以上版本
重写(toutUTF8);
WriteLn(toutUTF8,'АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ');


Consider this program:

{$APPTYPE CONSOLE}

begin
  Writeln('АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ');
end.

The output on my console which uses the Consolas font is:

????????Z??????????????????????????????????????

The Windows console is quite capable of supporting Unicode as evidenced by this program:

{$APPTYPE CONSOLE}

uses
  Winapi.Windows;

const
  Text = 'АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ';

var
  NumWritten: DWORD;

begin
  WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), PChar(Text), Length(Text), NumWritten, nil);
end.

for which the output is:

АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ

Can Writeln be persuaded to respect Unicode, or is it inherently crippled?

解决方案

Just set the console output codepage through the SetConsoleOutputCP() routine with codepage cp_UTF8.

program Project1;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,Windows;
Const
  Text =  'АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ';
VAR
  NumWritten: DWORD;
begin
  ReadLn;  // Make sure Consolas font is selected
  try
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), PChar(Text), Length(Text), NumWritten, nil);    
    SetConsoleOutputCP(CP_UTF8);
    WriteLn;
    WriteLn('АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.

Outputs:

АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ
АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ

WriteLn() translates Unicode UTF16 strings to the selected output codepage (cp_UTF8) internally.


Update:

The above works in Delphi-XE2 and above. In Delphi-XE you need an explicit conversion to UTF-8 to make it work properly.

WriteLn(UTF8String('АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ'));


Addendum:

If an output to the console is done in another codepage before calling SetConsoleOutputCP(cp_UTF8), the OS will not correctly output text in utf-8. This can be fixed by closing/reopening the stdout handler.

Another option is to declare a new text output handler for utf-8.

var
  toutUTF8: TextFile;
...
SetConsoleOutputCP(CP_UTF8);
AssignFile(toutUTF8,'',cp_UTF8);  // Works in XE2 and above
Rewrite(toutUTF8);
WriteLn(toutUTF8,'АБВГДЕЖЅZЗИІКЛМНОПҀРСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ');

这篇关于Writeln能否支持Unicode?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆