読者です 読者をやめる 読者になる 読者になる

C++Builder2009の新機能 その2

Unicode対応のテストとして、いくつかのテキストファイルをTMemoに喰わせてみる。まずは、こんなテキストファイ*1から。普通に保存するとShift-JISのはず。

ユーザー総員 傾注!

諸君 C++Builder2009が来た
無敵のBCB厨諸君 最古参のBCB厨諸君
万願成就の夜が来た
プログラミングの夜へ ようこそ!

当然と言えば当然だけど、Shift-JISならば今までと変わりない。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Memo1->Clear();
  Memo1->Lines->LoadFromFile("万願成就の夜が来た.txt");
}
//---------------------------------------------------------------------------

ただし、テキストファイルの文字コードUTF-8の場合は、エンコーディングを指定してやる。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Memo1->Clear();
  Memo1->Lines->LoadFromFile("yoshinoya.txt", TEncoding::UTF8);
}
//---------------------------------------------------------------------------

で、問題は、*nix系でデファクトスタンダード*2EUC-JPの取り扱いだけど、TEncodingにEUC-JPとUTF-16の相互変換は無いので、変換は自前でやらざるを得ない。ただし、以前と比べて大分楽になったはず。

キタ Y⌒Y⌒Y⌒Y⌒Y⌒Y⌒(。A。)!!!
キテナ━━━━(・A・)━━━━イ !!!!!
キタ━━━━━━(゚∀゚)━━━━━━━!!!!!
キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─ !!!
キタ─wwヘ√レvv〜(゚∀゚)─wwヘ√レvv〜─ !!!
ΣU゚Д゚;U キタ━━━━ヽU゚Д゚Uノ━━━━!!!!
バンジャ━━━━━∩( ・ω・)∩━━━━━イ!!!
キタキタキタ━━━━━━(゚∀゚≡゚∀゚)━━━━━━!!!!
キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─ !!!!!
キキキキ━━━━━(((((゚∀゚)))))━━━━━タタタタタ!!

半角カタカナを使った1行AAをEUC-JPで保存して、先ほど同様にTMemoに喰わせてみる。
コードとしてはこんな感じ。

//---------------------------------------------------------------------------
typedef AnsiStringT<20932> EucJpString; // 20932は、EUC-JPのコードページ

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Memo1->Clear();

  std::ifstream infs("kitaa-euc.txt");
  std::string buff;

  while (std::getline(infs, buff)) {
    EucJpString eucs(buff.c_str()); // EUC文字列
    UnicodeString us(eucs);         // キャストによってEUC-JP→UTF-16の変換を行う
    Memo1->Lines->Add(us);
  }
}
//---------------------------------------------------------------------------


キモは一番最初のtypedefで、今回からAnsiStringがテンプレート化され、テンプレートパラメータに文字列のコードページ*3を指定出来るようになりました。コードページに20932を渡せば、その文字列クラスは中身がEUC-JPである文字列クラスとなります。ただし、Lengthメソッド文字数でなくバイト数になるので注意。あとは、キャストがよろしくやってくれるので、nkf.dllやiconv.dllを呼び出したり、WideCharToMultiByteの類を使用する必要は無くなりました。

21:25 追記:やばいかもと言う指摘があったので、「多分」と言うことで。でも、本当に文字コードの変換は地獄だ。('A`)

VCLにおけるUnicodeの詳しい説明は、Developer Networkでの高橋さんの記事を参考にして下さい。
Delphi Unicodeワールド パートI
Delphi Unicodeワールド パートII
Delphi Unicodeワールド パートIII

*1:中身については突っ込み禁止。

*2:最近はUTF-8がトレンドになりつつある。Solaris10とかUbuntuとか。

*3:コードページ一覧はここ