wchar_t

I was just wondering, why doesn't this print UNICODE characters. I expected loads of them, but it just printed normal ASCII characters...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <conio.h>

int main()
{
    using std::wcout;
    for(int i(0); i < 65536; i++)
    {
        if(i % 24 == 0) wcout << '\n';
        wcout << wchar_t(i) << ' ';
    }
    getch();
    return 0;
}
The untold truth about wcout...

It cannot perform Unicode output... (without a lot of help).

If you are on nix, you've got it made... since many modern terminals support UTF-8 encoded data.

So, convert your wchar_t strings to a UTF-8 sequence and print it using cout.

If you are on Windows, you haven't got it as easy... you've got to set up a UTF-8 enabled terminal for your user and install your program to use it.


I'm going to make this into an Article, but here you go for a quickie.

We're going to create a .lnk file to create a UTF-8 aware command prompt. Now, .lnk files are typically not copyable to other systems... but this one is special.

Open Explorer and navigate to your program's directory. Right click on an empty spot and choose "New Shortcut".

Name it something like "RunUTF8k.lnk".

On the "Shortcut" tab, make the Target
%ComSpec% /u /k @chcp 65001&&@cls&&"%RUNUTF8%"

On the "Font" tab, make sure that the font reads Lucida Console. A size of 14 or so is nice also.

If you want to play with the window position, now is the time to do it with the "Layout" tab.

Save it all.

Now create a batch file, called "RunUTF8k.bat".
1
2
3
4
5
6
@echo off
if %1.==. goto :end
for %%F in (%1) do set RUNUTF8=%%~fF
start RunUTF8k.lnk %*
set RUNUTF8=
:end


The neat trick with this particular shortcut/batch file pair, is that you can copy it to other systems and it will usually work. Keep in mind that it works by calling the user's command shell through the usual environment variable substitutions... so make sure not to give your program shortcut any greater security permissions than strictly necessary.

Now you can execute your program by calling
runutf8k path\to\myprog.exe arg0 arg1 ...


Again, your program should output Unicode text using UTF-8 encoded strings.

If your STL has the <codecvt> class working properly, you can imbue wcout with a std::codecvt_utf8 enabled locale:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <codecvt>
#include <iostream>
#include <locale>
using namespace std;

int main()
  {
  locale loc( locale(), new codecvt_utf8 <wchar_t> );
  wcout.imbue( loc );

  wcout << L"STΛRGATE ΛTLΛNTIS\n";

  return 0;
  }

Hope this helps.
@OP to let wcout print out wide characters, you need to imbue it with the appropriate locale (it's imbued with the minimal locale at program startup):

1
2
    std::locale::global(std::locale(""));
    std::wcout.imbue(std::locale());

(replace "" with a named locale such as "en_US.utf8" in case you want to print non-ASCII characters even if the user requested the C locale, but it's questionable)

live online demo: http://ideone.com/7Ta6Ft


Microsoft Visual Studio, infamously, does not provide standard-compliant Unicode support for C or C++ except where forced by the C++11 standard, so it has a different magic incantation to make standard output accept wide characters:

_setmode(_fileno(stdout), _O_WTEXT);
(you need to include <fcntl.h> and <io.h> -- see MSDN for details)

@Duoas UTF-8 in general and codecvt_utf8 specifically has nothing to do with wcout.
Last edited on
Topic archived. No new replies allowed.