イネマルのプログラミング備忘録

趣味プログラマーのメモ

C++でワイド文字(wchar_t)を使うときの注意点 ~ロケールを添えて~

f:id:inemaru:20150923003606p:plain

wchar_tを使う!

c++で文字を扱うときに、char型とwchar_t型があります。
char型と同じ感覚で使うと、要らないところでハマります。
自分がハマったので備忘録行き。

先に、結論だけ書くと
”wchar_tを使うならロケール設定をしよう!”
という事です。

確認用のプログラム

C++で現在のロケールを取得しながら
処理を目で追ってみました。

ロケールを取得した段階で "C" が返ってきたら危険。
即座に、設定するべきでしょう。

※動作確認は、VC2010とVC2013で行いました

#include <iostream>	// 標準入出力
#include <locale>	// ロケール関連
#include <clocale>	// Cのロケール関連
#include <string>	// stdの文字列クラス

using namespace std;

int main(){
	// 適当な文字列変数
	string	str("char");
	wstring	wstr(L"wchar_t");

	// ロケールを表示する関数
	auto DispLocale = [](){
		string locstr = std::locale().c_str();
		if(locstr == "C"){
			locstr += "(初期値です)";
		}
		cout << "現在のロケールは、" << locstr << endl << endl;
	};

	// 現在のロケール設定を表示
	DispLocale();

	// char文字の出力
	cout << str  << " char(string)は特に設定なしで表示できる" << endl << endl;

	// wchar_t文字の出力
	cout << "ロケールの設定なしでwcoutすると強制的にwcoutの処理が打ち切られる?" << endl << endl;
	// wcout << wstr2 + L"日本語は表示されない" << endl;
	
	// ロケールの設定
	cout << "ロケールの設定を変更します" << endl << endl;
	locale::global(locale(""));	// ""で処理系のシステムのデフォルトになるそうです
	// もしくは、
	//locale::global(locale("japanese"));
	// かつ、WindowsAPIを使うなら
	//setlocale(LC_ALL,"japanese");

	// 変更されたロケール設定を表示
	DispLocale();

	// wchar_t(wstring)は設定すると表示できる
	wcout << wstr + L" 日本語が表示される!" << endl << endl;
	
	rewind(stdin), getchar();	// キー入力で終了

	return 0;
}

あとがき

以下のリンクがすごく参考になりました。
Windows API on C++

単純にwchar_tで日本語が使いたいのであれば
std::locale::global(std::locale(""));
の一行で一応動いているようです。

ただし、WindowsAPIを使用するなら
std::locale::global(std::locale("japanese"));
std::setlocale(LC_ALL,"japanese");
とするべきでしょう。