Unicodeの落し穴 - 文字コードと文字列処理

宇宙の境界条件は、それが境界を持たないということだ。
スティーヴン・W・ホーキング 『ホーキング、宇宙を語る
Unicodeといえば、文字コードの一種。文字コードをあまり意識しない方でもほとんどの方は御存じでしょう。しかし、Unicodeというか文字コードに関して、いくつかありがちな誤解があり、それが原因でバグにはまることもあります。ということで、今回はUnicodeと文字コードの話です。

■文字コードと符号化方式

4798100307文字コードといった時によく、混同されるのが文字集合(character set)と符号化方式(encoding type)。文字集合はその名のとおり、文字の集合を定義したもので、日本語であれば JIS X 0208(第一、第ニ水準)をはじめ、JIS X 0212(補助漢字) 、 JIS X 0213(第三、第四水準)等があります。 それに対して、符号化方式とは、文字集合に含まれる各文字をどのようなコードに割り当てるのかというもの。 1つの文字集合JIS X 0208に対しても、ISO-2022-JPShift-JISEUC-JP等があります。この辺の話は、textファイルやソースコードの編集時や、Webページの閲覧時に問題になることが多いので馴染み深いですよね。
そして、問題のUnicodeですが、これは多言語を同時に扱うことを目的として開発された文字コード体系です。符号化方式は可変長の8ビットコードであるUTF-8、16ビットもしくは32ビットでエンコードするUTF-16等があります。

さて、ここまでで何が問題なのかというと、Unicodeを符号化方式を表すものと勘違いしている人がいることです。UTF-8とUTF-16はともに良く使用される符号化方式ですが、「Unicode文字列を処理する」といった場合に、どちらか一方でエンコードされていることを期待しているソースコードを書いてしまい、それがバグの原因になることがあります。

■ワイド文字列・マルチバイト文字列の文字列処理

プログラミングにおいて、文字コードが直接影響するのは文字列処理です。C言語でいれば、strcpy, strcmp, printf等など。C言語における文字列は、「NULL終端文字('\0')までのバイト列(char配列)」というのは、これは、ASCIIを始めとする1バイト文字列での話。ワイド文字列では、これが「ワイドNULL文字('\0\0' 2バイトの0)までのワイド文字列」となります。
これはつまり、ワイド文字列に対してstrcpy等の従来の文字列処理のライブラリが使えないということを意味しています。内部で、strcpy等を利用しているライブラリも同様です。ワイド文字列では、終端以外でも0が入ることがあるので、意図しないところで終端扱いされ、途中までしか文字列がコピーされないといったようなことが起こります。

Unicodeに関しては、UTF-8でエンコードされている間はNULL終端文字を期待する従来の文字列処理関数が使用できますが、これがUTF-16だとそうはいきません。よって、Unicode対応をUTF-8対応と思っていると、strcpyを使っているようなコードでも問題ないと判断してしまいそうですが、実はUTF-16への対応が必要だったという場合にバグを引き起こします。

■資産の流用と文字コード

Unicode自体はまだ発展途上とも言える技術ですが、徐々に使用範囲が拡がっています。よって、今まではUnicodeを扱わなかったようなライブラリでも、Unicode文字列を扱わなければならないケースがあるでしょう。その際には、文字コードにおける符号化方式の違い、ワイド文字列に対する互換性問題に対して、正しい認識を持って問題にあたることが必要でしょう。

【関連書籍】
Unicode標準入門 トニー・グラハム 乾和志
Cプログラミングの落とし穴 A.コーニグ
文字コード超研究 深沢 千尋
プログラミング言語C ANSI規格準拠 B.W.カーニハン D.M.リッチー
図解入門 よくわかる最新ファイル形式と文字コードの基本と仕組み―データ形式、ファイル構造、文字コード基礎講座

【関連リンク】
Unicode (Wilipedia)
文字コード (Wikipedia)
Manpage of PRINTF

コメント

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます
非公開コメント

本のおすすめ

4873115655

4274065979

4822236862

4274068579

4822255131

B00SIM19YS


プロフィール

  • Author:proger
  • 組み込み関係で仕事してます

ブログ内検索