マルチバイト文字
2019-07
マルチバイト文字(マルチバイトもじ)とは、コンピュータ上で
1文字を複数バイトで表す体系(文字コード)
を指すが、文脈により意味合いが異なる。
ISO 2022の体系を前提とした図形文字集合において、1文字が1バイトの文字集合(single-byte character set、94文字集合または96文字集合)に対して、1文字が2バイト以上の文字集合を、マルチバイト文字集合(multibyte character set)という。94×94文字集合(2バイト)、96×96文字集合(2バイト)、94×94×94文字集合(3バイト)などがこれに該当するが、実際には94×94文字集合以外はまれである。
特に、1文字が2バイトの文字集合を2バイト文字集合(double-byte character set)といい、以下のようなものがある。
JIS X 0208 (JIS C 6226)
KS X 1001 (KS C 5601)
なお、2バイト文字集合の文字のことを2バイト文字と呼ぶことがある。しかし、1バイト文字集合の文字であっても、EUC-JPにおけるJIS X 0201カタカナなどのように、符号化方式によっては一見1文字あたり2バイトであるかのような符号化をされることがある。また2019-07では、Unicode で処理することも多い。そのため、文字集合でなく個々の文字を指して1バイト文字・2バイト文字と表現することは、混乱を招くことがある。
符号化方式において、1文字が常に1バイトとなる符号化方式に対して、1文字が2バイト以上になることのある符号化方式、およびそれによって符号化された文字(列)のことを、マルチバイト文字(列)という。
実際には、ほぼ例外なく ASCII あるいは ISO 646 をベースとし、バイト値 80 - FF16進法(あるいはそのサブセット)で始まるバイト列によりそれ以外の文字集合を表現する。
1文字のバイト数が可変のため、プログラムでの操作に留意を要する。
符号化方式であるから厳密には character set(文字集合) と呼ぶのは不正確だが、とくにIBMやマイクロソフトの用語として、single-byte character set(単バイト文字集合)、double-byte character set(2バイト文字集合)、multibyte character set(多バイト文字集合)と呼ぶことが多い。
以下のようなものがある。
Big5(コードページ950)
EUC-CN(コードページ936)
EUC-KR(コードページ949)
Shift_JIS(コードページ932/942)
UTF-8(多バイト符号化方式)
C言語の規格において、char型以上のサイズを持つwchar_t型を利用したワイド文字(列)に対して、char型を利用して1文字あたり1バイト以上の可変長のバイト列として表したものをマルチバイト文字(列)という。ワイド文字に対する用語のため、1文字をもっぱら1バイトで表すシングルバイト文字であっても、この意味ではマルチバイト文字に含まれる。
ワイド文字を内部処理に用いるプラットフォームもある。ワイド文字のサイズが2バイトあるいは4バイトの場合、本来1文字ごとに1バイトで収まるはずのASCII範囲の文字にも2バイトあるいは4バイトを費やすことになり、少なくともASCII範囲に関してはメモリ効率は劣ることになるが、処理対象のデータ中にマルチバイト文字で表現すると2バイト以上を費やすような文字が多数出現する場合は、ワイド文字を利用したほうが処理効率もメモリ効率も高くなることがある。
ワイド文字およびマルチバイト文字の具体的な表現は環境依存であり規格には定めがない。これらは、実在する具体的な文字集合や符号化方式を分類する用語ではなく、固定長か可変長かという概念を定義した用語である。そのため、何がワイド文字で何がマルチバイト文字かという考え方ではなく、ワイド文字の表現として何を使い、マルチバイト文字の表現として何を使うか、という考え方をとる。ワイド文字としては、2019-07では Unicode が使われることが多い。マルチバイト文字の符号化方式はロケールに依存するが、ほとんどの場合は ASCII あるいは ISO 646 をベースにしたものとなり、日本語ロケールであれば一般的に Shift_JIS や EUC-JP になる。UTF-8 が用いられる場合もある。
ワイド文字は当初、文字集合におけるすべての文字を等しいサイズのデータで一様に処理できるようにすることを想定していた。しかし、Unicodeにおいてサロゲートペア、結合文字、異体字セレクタといった拡張概念が採用されたことにより、UTF-16やUTF-32といった符号化方式のデータをワイド文字に格納する場合、たとえワイド文字が16ビットあるいは32ビットのサイズを持っていたとしても、1つのワイド文字だけでは表現できないUnicode文字も現れるようになった。文字境界の判定や文字数のカウントなど、プログラム上での扱いはマルチバイト文字と同様に注意を要する。
C言語(C95以降)では、マルチバイト文字(列)の操作のために以下のような関数が規定されている。ただし、特に日本語のような2バイト文字集合を含むロケールでは、実装が不十分で実用に耐えない場合も多い。
mblen
mbtowc
wctomb
mbstowcs
wcstombs
Microsoft Windowsでは、ワイド文字が2バイト(16ビット)として定義されており、符号化方式にUTF-16を利用する。多くのWindows APIには、入出力インターフェイスとして、システムロケール設定に依存するマルチバイト文字セットを利用する関数・構造体(シンボル末尾にAが付けられている)と、Unicode文字セットを利用する関数・構造体(シンボル末尾にWが付けられている)の両方が用意されており、ヘッダーファイルをインクルードする際に_UNICODEシンボルの定義有無でマルチバイト文字セット/Unicode文字セットを切り替えることのできるプリプロセッサマクロも用意されているが、マルチバイト文字セット用のAPIはWindows 9x系向けに書かれたコードとの互換性のために残されているものであり、またWindows NT系では内部処理にUTF-16を使用しているため、マルチバイト文字セット用のAPIを使用すると変換のための余計なオーバーヘッドが増える。Microsoft Visual C++はバージョン7.1 (2003) まではマルチバイト文字セットが既定値だったが、バージョン8.0 (2005) 以降はUnicode文字セットが既定値となった。マルチバイト文字列の操作や、ワイド文字列との相互変換のために以下のようなAPI関数が提供されている。
MultiByteToWideChar
WideCharToMultiByte
CharNextA
CharPrevA
シンボル末尾にAが付けられたマルチバイト文字セット用API関数は、コードページ番号を明示的に指定できず、動作はシステムロケール設定に依存する。
2019-07、符号化文字集合としての ISO 10646(Unicode)、およびその符号化方式(UTF-8、UTF-16など)が広く使われている。
文字集合としての ISO 10646 は、1バイト=1オクテット(8ビット)と定義すれば、一応マルチバイト文字集合ということはできる。しかし、現実的には、1バイト文字集合とマルチバイト文字集合という分類の前提となっているのは、「1バイト文字集合(ASCII、ISO 646)を基本としつつマルチバイト文字集合を導入する」という命題であり、単一文字集合である Unicode を採用する時点でこの前提自体が崩れている。
符号化方式としては、シングルバイトの符号化方式と対比した場合、UTF-8 などはマルチバイトの符号化方式といえる。UTF-16 などは ASCII 互換でないため考慮されないことが多い。また、ワイド文字の文脈では、一般にワイド文字としては UTF-16 や UTF-32 を使い、マルチバイト文字としては、UTF-8 などを使う場合と、従来の Shift_JIS などを使う場合とがある。