0

I am attempting to write the following character out in windows command prompt: ュ (U+FF6D).

I am able to see the character get written out using WriteConsoleW. I am also able to see the character if i use WideCharToMultiByte using the CP_ACP code page (chcp returns 932: Japanese). However, when I attempt to use regular wcout on the same string which WriteConsoleW successfully prints, it chokes.

When I execute setlocale(LC_ALL, "") it prints English_UnitedStates.1252 (the default code page that I had when I installed).

Why is wcout failing when the others are succeeding?

Note: I rebooted the machine to change its system locale to Japan Japanese

Craig Trader
  • 15,507
  • 6
  • 37
  • 55
bogertron
  • 2,255
  • 1
  • 24
  • 36

2 Answers2

2

The default locale for C++ iostreams is always the "C" locale. From the C++03 standard, §27.4.2.3/4:

locale getloc() const;

If no locale has been imbued, a copy of the global C++ locale, locale(), in effect at the time of construction.

From §22.1.1.2/1-2:

locale() throw();

Default constructor: a snapshot of the current global locale.

Constructs a copy of the argument last passed to locale::global(locale&), if it has been called; else, the resulting facets have virtual function semantics identical to those of locale::classic().

From §22.1.1.5/4-6:

static const locale& classic();

The "C" locale.

Returns: A locale that implements the classic "C" locale semantics, equivalent to the value locale("C").

Notes: This locale, its facets, and their member functions, do not change with time.

As std::cout and std::wcout have static storage duration, they are guaranteed to be initialized before main is called, and consequently will always have the "C" locale at application startup; i.e., there is no point early enough in execution that one can call locale::global and change the default locale for std::cout and std::wcout. Thus, you must always imbue the global streams yourself if you want to use a non-default code page.

Community
  • 1
  • 1
ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • So I guess that this is a windows specific question then. At no point have I called cout.imbue within my application, however it can still handle the code page character. I was under the assumption (yes assumption evil thing) that wcout would have imbue'ed the same locale. – bogertron Apr 22 '11 at 00:02
0

wcout is created before any code in main executes. By the time you call setlocale, wcout is already there, ready to do its thing. It makes no attempt at tracking subsequent changes you might make with setlocale, so it continues to use the default instead of whatever you set with setlocale.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • OK, that makes sense, but if I my machine booted up with a locale which is capable of printing the character (U+FF6D) has a mapped character to CP 932. I guess my question is how is the default locale for wcout defined? – bogertron Apr 21 '11 at 23:52
  • @bogertron : My answer addresses that aspect of the question. – ildjarn Apr 21 '11 at 23:54