Windows Vista における JIS 2004 のサロゲート文字を開発で扱う際の留意点


【環境】
Windows Vista

こんにちは。

出張前で書き溜めた状態になっていますが、Windows Vista における JIS 2004 のサロゲート文字を扱う際のコード上の留意点について記載します。本件は、昨日群馬で実施した Microsoft On においてご質問頂いたものです。(高崎の参加者の皆様、お疲れ様でした、、、)

ここでは、JIS 2004 とは何か、サロゲート文字とは何かという点の詳細はご存知という前提で記載しませんが、こちらの Hiroyasu Kitagawa's Blog やその中からリンクされている日経 IT Pro の記事、MSDN における情報などが役に立ちます。
簡単に記載しますと、JIS 2004 で 4 バイト扱いの文字が存在しているのですが、.NET の String の内部コードである UTF-16 においても今までの文字(アスキー、JIS)の2文字分 (要は、.NET のChar 2つ分) となっているため、Char のインデクスをベースとしている String クラスの一部メソッドなどでは、サロゲート文字を含むと期待と異なる動きをすることがありますので注意が必要です。
日経 IT Pro にも記載されていますが、通常は、非常なクリティカルな処理をおこなっている業務システムなどでは、入力時にチェックをおこなう、Vista 側に従来のフォントをデフォルトとして設定する、XP 側に JIS 2004 フォントを導入する、など対処方法が存在していますのでケースによってはこうした方法をお勧めしますが、.NET 上でサロゲート文字を扱いたい場合には、以下のようなケースに配慮してください。

まずは、実験をしてみましょう。
Vista と Visual Studio をお持ちの方は、Windows アプリケーションのプロジェクトを新規作成し、フォーム上にテキストボックス(textBox1 とします)とボタン (button1 とします) を配置して、ボタンの Click イベントとして以下を実装してみましょう。

private void button1_Click(object sender, EventArgs e)
{
  MessageBox.Show(textBox1.Text.substrng(1, 1));
}

では、デバッグ実行で、「叱る」(シカル)と入力し、変換で出てくる候補で、「環境依存文字」と書かれた正字の "叱る" を選択して入力して、ボタンを押してみてください。すると、インデクス1(0 が開始です)に相当する「る」ではなく、空のメッセージボックスが表示されると思います。

この理由は、

http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpref/html/frlrfsystemstringclasstopic.asp

に記載されている通り、substring 関数が、Char のインデクスに基づいて処理していることに依ります。
これを回避するために、.NET には、StringInfo というクラスが存在します。上記の処理を StringInfo を使った処理に書き換えます。

using System.Globalization;

private void button1_Click(object sender, EventArgs e)
{
    StringInfo strinfo = new StringInfo(textBox1.Text);
    MessageBox.Show(strinfo.SubstringByTextElements(1, 1));
}

StringInfo では、サロゲート文字も含めた「文字情報」を認識するクラスのため、今度は期待通り、「る」が表示されるはずです。

StringInfo クラスは、何も Vista 用に追加された新しいクラスというものではありませんので、ある意味、「正しく組まれたコードは変更しなくて良い」 とも言えますが、上記のような処理は、ついついコードに混在してしまいがちですね(私が同じ処理を組んでも、間違いなくこのように String クラスを使って記載していることでしょう)。Windows Vista でサロゲート文字も含めた処理をお考えの方は、こうしたポイントにご留意ください。

 


Comments (1)

  1. マイクロソフト社は1月30日、最新OS、ウインドウズ・ビスタを世界同時に発売したが、日本では冷ややかな反応となっている。

Skip to main content