g++ でwcout使って日本語をコンソールに出力

どうもです。


3文字のカタカナの組み合わせをほぼすべて作成する必要が生じまして,
せっかくなので,C++でやろうということで,挑戦したものの,
例外をすっぽなげられて,少しはまったので,メモ。


あぁ,別に怪しいことをしようとしたわけではないですよ。
怪しいことって何なのかよくわかりませんが,Brute Force Attackとか,
レインボーテーブルを作ろうとか,そういうことではございません。
ふりじゃないんだからねっ。

環境

Windows XPSP3, Cygwin 1.7.7。

結論

Cのsetlocale使っとけ。

#include <iostream>
#include <clocale>

using namespace std;

int main()
{
  setlocale(LC_ALL, "ja_JP.UTF-8");
  const wchar_t msg[] = L"じゃ,あたし生徒会行くね。";
  wcout << msg << endl;

  return 0;
}

過程

#include <iostream>
#include <locale>

using namespace std;

int main()
{
  const wchar_t msg[] = L"ほんとにニートになっちゃうよ。";
  wcout.imbue(locale("ja_JP.UTF-8"));
  wcout << msg << endl;

  return 0;
}

これを実行すると,

% ./widechar
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
zsh: abort (core dumped)  ./widechar

と,例外がすっぽ投げられる。


理由は,下記サイトが参考になります。感謝!
http://d.hatena.ne.jp/eagletmt/20090208


上記サイトの環境とワタシの環境は違うけど,メッセージが同じだから,
たぶん同じじゃね? ってな感じです。


imbue() ってなんじゃらほいっと cppref 探したけど,
見つからなかった。
なので,cplusplus.comの方から引用。
http://www.cplusplus.com/reference/iostream/filebuf/imbue/

virtual protected member function

void imbue ( const locale & loc );

Imbue locale

Associates the locale object loc to the file buffer.

A locale object contains culture-specific information on how to interpret certain input and output
operations.

The public member function pubimbue of the parent class streambuf calls this virtual member function,
which overrides the virtual member streambuf::imbue.


簡単に言うと,バッファにロケールを設定するという感じか。
ちなみに,imbue は,インビューとよむ。アクセントは後ろ。
初めて知った単語だ。「〜を満たす」みたいな意味。

まとめ

setlocale() 使っとけ,ということでよろしいでしょうか。


ちなみに,ja_JP.UTF-8 にして,「あ」を16進で出力すると,
「0x30a2」になったんだけど,ググると,これは,UTF-16文字コード
ようだ。そういうもんなんかなぁ。
文字コードはほんとよくわからん。