cygwinのgcc/g++で文字化け

とある事情で「ロケットガール」を見ながら、c/c++の本を書いています。c/c++の本では、windows環境とlinux環境で動作確認をするわけですが、あっちこっちに移動するのが面倒なので、前チェックとして cygwin の gcc/g++ を使っています。

# 「ロケットガール」のほうは後日

さて、Visual C++ 2008 と gcc/g++ ですが、微妙に動作が違います。標準関数系はだいたい同じ(って同じじゃないと困るけど)なんですが、例外やらエラーの発生の仕方が異なります。なので、例外(try-catch)を使って受け取ったときに、メッセージを出力してチェックすることになります。

#include <string>
#include <iostream>
using namespace std;

int main( void )
{
 string str1("Hello C++ world.");
 int n;
 
 try {
  n = 4;
  cout << n << "バイト目:[" << str1[n] << "]" << endl;
  n = 100;
  cout << n << "バイト目:[" << str1[n] << "]" << endl;
 } catch ( ... ) {
  cout << "エラーが発生しました " << endl;
 }
 return 1;
}

これを、コマンドラインでコンパイルして、コマンドラインで実行、ってことになります。

cygwin のシェルを立ち上げて、実行すると

<001>
20100122_001

な具合に文字化けします。これは、cygwinをインストールした直後にシェルのLANG 環境変数を設定していない場合に、発生します。

なので、日本語(SJIS)が通るように、

export LANG=ja_JP.SJIS

を設定してやると、次のように文字化けせずに済みます。

<002>
20100122_002

そんな簡単な話なんですけどね、しばらく使っていないもので結構悩みました。
unicodeが動作するように、wstringを使ってwcoutを利用して出力、setlocate忘れ、で文字化け、なんてのはよくやるのですが。

#include <string>
#include <iostream>
#include <locale.h>
using namespace std;

void main( void )
{
 string str1("Hello world.");
 string str2;
 
 str2 = str1;
 cout << str2 << endl;
 str2 = "Hello C++ world.";
 cout << str2 << endl;
 str2 = 'C';
 cout << str2 << endl;
 // Unicodeを使う
 setlocale(LC_CTYPE, ""); // これが必須
 wstring s;
 s = L"ようこそ C/C++ の世界へ";
 wcout << s << endl;
}

まあ、ライブラリを作るときは、こういうことに悩まないためにメッセージを英語にしておくのが無難ですね。
「文字コードはunicodeで統一される」と言われて、十数年経ちますが、結局のところ統一されることはないようですので。まだまだ、ASCII(7ビット文字)が現役です。将来的に中国語がのして来るとbig5が多くなったりして。

カテゴリー: 開発 パーマリンク

cygwinのgcc/g++で文字化け への5件のフィードバック

  1. k1496 のコメント:

    仕事先が中国から搾取してる商社なので、中国語の扱いが微妙です。

    unicodeって言われてそんなに経つんですね。

    簡体字 GB2312
    繁体字 Big-5

    知らなかったです。

    中国でも地域によって異なってるらしく、大体簡体字なんですが、台湾は繁体字、間に日本語と面倒です、ほんと。

    バベルの塔って感じ。

  2. masuda のコメント:

    # 何処に落とすかが微妙なので、まぁ、それぞれ。

    Big5は何かのコード判別で使ったけど、EUCと同じで扱いやすかったと思う。
    簡体字のほうは、よくわからんけど、Unicodeでのバッティングが多かったハズ。
    ヨーロッパの人から見ると、どちらも「わからない文字」でしかないからね~。

  3. valp のコメント:

    文字コードの統一が進まないのは相変わらずですが、それでもCygwin以外(Linux, BSD, Mac OS X, …)はみんなUTF-8 locale (ja_JP.UTF-8など)が主流になりつつあるので、なんだかんだでUnicodeの影響力をじわじわと感じます(おかげでUTF-8以外ではまともに動かないアプリケーションもぼちぼち出てきて困ったものです)。

    そのWindowsもNTの最初から内部のAPIはUnicode (のちのUTF-16)で、裏方では抜きに考えられないのですが、なかなか浸透しませんねえ。

  4. masuda のコメント:

    プログラマ的には UTF16(旧Unicode)の16bitで統一してほしかったんですけどね。欧米の都合で UTF8 が蔓延してしまったので、正規表現ライブラリのような文字列系のライブラリが作りづらいという(パフォーマンスを気にしなければ、UTF8 – UTF16 の相互変換をすればいいんですが)。

    Windows 計の場合は、中身が早々に UTF16 にしたのに、DOS プロンプトが SJIS(各国ローカル)になっているのが致命的ですよね。。。DOS プロンプトを一気に UTF16 にしてしまえば、コマンドライン系も UTF16 になって幸せだったのに…というのは 10年前の MS の失策。

  5. masuda のコメント:

    当時、C 言語界隈で、char を全廃して、byte と wchar_t だけにしてしまえば、それでよいのに、という「暴論」もありましたが、今思うとそれほど暴論でもなかったかなぁと。

コメントは停止中です。