Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Bob Swart (aka Drs.Bob) Dr.Bob's Delphi Clinics Dr.Bob's Delphi Courseware Manuals
View Bob Swart's profile on LinkedIn Drs.Bob's Delphi Notes
These are the voyages using Delphi Enterprise (and Architect). Its mission: to explore strange, new worlds. To design and build new applications. To boldly go...
Title:

Unicode tip #9 - Console Output

Author: Bob Swart
Posted: 12/11/2008 12:29:22 PM (GMT+1)
Content:

First the bad news: console I/O does not support reading (UTF-16) Unicode strings, and writing only suports AnsiStrings. This means that as soon as you call write or writeln, the contents of a (unicode) string will be converted to AnsiString when needed, and written to the output.

This means that any Text file I/O needs to be rewritten using streams or other techniques. However, since a UTF8String is also an AnsiString (with the 65001 code page specified), there is a good workaround for writing to console output provided you set the console codepage to UTF-8 and use a font that can display the Unicode characters (that’s Lucida Console for example):

  program ConsoleUTF8;
(*$APPTYPE CONSOLE*)
uses
Windows, SysUtils;

begin
SetConsoleOutputCP(65001);
// Writeln(UTF8String('[???????????? ???????]')); // normal Unicode String, now "????"
Writeln(AnsiString('[наименование проекта]')); // UTF-8 cyrillic "hack"
readln
end.
This will produce cyrillic characters on the standard output, if you use Lucida Console as font (just try it - copy and paste into the Delphi 2009 IDE). Note that Lucida Console cannot display all Unicode characters – Chinese and the Clef are not shown, but at least cyrillic characters display without problems.

Note that I do not have to write the BOM to the output (you may want to in case you want to save the console output to a text file and read it afterwards. That way, you can set the font afterwards and also see the Chinese or Clef characters without problems. Provided they were written as UTF-8).

As long as we convert UTF-16 Unicode Strings to UTF-8 before writing to Text files, and don’t forget to use the UTF-8 BOM as prefix, this will work fine for writing files with Unicode UTF-8 output.

This tip is the 9th in a series of Unicode tips taken from my Delphi 2009 Development Essentials book published earlier this week on Lulu.com.

Back  


4 Comments

AuthorPostedComments
fredG 08/12/11 13:42:44Are you saying that the programs writing unicode chars to the console do some kind of cheating? Or is this possible in C, but not in Delphi?
Bob Swart 08/12/11 14:02:14Delphi's console output is limited to AnsiStrings (and UTF8Strings are some kind of AnsiStrings as well). You cannot write UTF-16 Unicode Strings to the console output using Delphi without converting them to UTF-8 first. This may be possible in C, I don't know (don't care). Delphi needs UTF-8, and here I show how...
Marshall Fryman 08/12/11 19:31:58Using Vista, you can programmatically force the console font to be Lucinda using SetCurrentConsoleEx. Unfortunately, it's not possible with any older OS which limits its functionality. There's a good reference to older OS solutions here: http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.win32.programmer.international&tid=f03fbeca-27f1-466c-aa6f-1d2735a2fd41&cat=&lang=&cr=&sloc=&p=1. If anyone is interested, you can't use WriteConsoleW and redirect to a text file (i.e., myprog > tst) because of how WriteConsoleW works. You have to detect the output mode as shown in this example : http://blogs.msdn.com/michkap/archive/2008/03/18/8306597.aspx and use WriteConsoleW or WriteFile. You might also be interested to note that your solution works fine in Delphi 2007 also. m
Bob Swart 08/12/11 20:10:06Thanks for the feedback Marshall. http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.win32.programmer.international&tid=f03fbeca-27f1-466c-aa6f-1d2735a2fd41&cat=&lang=&cr=&sloc=&p=1 is indeed an interesting link.


New Comment (max. 2048 characters, no HTML):

Name:
Comment:



This webpage © 2005-2014 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.