からあげの備忘録

ダメ社会人。継続は力。

マルチバイト文字とワイド文字

マルチバイト文字

Shift_JISUTF-8といった文字コードでは1文字を表現するための大きさが一定ではありません。
このような文字コードはマルチバイト文字と呼ばれます。
MSDNによると1バイト以上のシーケンスで構成される文字はマルチバイト文字らしいので、
マルチバイト文字とワイド文字 | Microsoft Docs
ASCIIコードもマルチバイト文字に含まれるようです。
C言語のchar型を使用して表現する文字はマルチバイト文字です。

ワイド文字

C言語の文字型にはchar型ともう1つ、wchar_t型が存在します。
このwchar_t型で表現する文字のことをワイド文字と呼び、全ての文字を同一バイト数で表します。
char型は規格で8ビットと決まっていますが、wchar_t型は環境依存なので16ビットだったり32ビットだったりします。

ワイド文字、ワイド文字列のリテラルには、下記のように接頭辞 L を付けます。

wchar_t wc = L'あ';			// ワイド文字
wchar_t wstr = L'あいうえお';	// ワイド文字列

基礎知識:Unicode

Unicodeとは

世界中のすべての文字を扱うことを目的として作られた符号化文字集合で、アルファベットや記号はもちろん漢字やひらがな等、世界中で使用されている文字の集まりです。
※元々は全ての文字を16ビット(256*256=65536文字)に収めるという方針だったが、現在はさらに拡張されている(21ビット)

BMPと拡張領域

BMP:Basic Multilingual Plane

基本多言語面とも呼ばれ、16ビット時代のUnicodeで既定された文字表

拡張領域

16ビット以降のバージョンで拡張された部分

Unicode文字符号化方式エンコーディング

Unicode文字符号化方式には下記のような種類があります。

UTF-8 :1文字を8~32ビットで表現

ASCIIの文字をそのままUnicodeで使用可能にするために制定された。
そのため、ASCIIに相当する部分は1バイトで、その他の部分は2~4バイトで表す可変長の符号化方式

UTF-16:1文字を16~32ビットで表現

Unicodeに収録されている文字のうち、BMP領域割り当てられているものを16ビットで表し
その他の領域に収録されている文字を4バイトで表します。(サロゲートペアという)
Windowsが採用しているUnicode文字符号化方式

UTF-32:1文字を32ビットで表現

※符号化文字集合文字符号化方式については下記記事を参照

UTF-16をもう少し詳しく

UTF-16には下記の2種類が存在する

エンディアンを識別するために、文書の先頭にはBOM:byte order markが付加される
UTF-16LEでは先頭2バイトに0xFF, 0xFEが付加される
UTF-16BEでは先頭2バイトに0xFE, 0xFFが付加される

基礎知識:文字コード

文字コード」と聞いたときに、Unicode, UTF-8, UTF-16, Shift-JIS, ASCII等色々な言葉が思い浮かんでいたのですが(そもそも、この時点で混同していた)
そもそも具体的に勉強したこともなく、何となくで来てしまったので勉強し直しました。

文字コードとは?

文字集合を定義し、その集合の各文字に対応する数値を一意に定めたもの]が文字コードです。
今回勉強してみて分かったのですが、そもそも「文字コード」という1つの概念でコンピュータでの文字について理解しようというのが間違っていました。

符号化文字集合文字符号化方式

文字コードには下記の2つの要素があり、これをしっかりと意識しておかないと、私のように後々混乱してしまうことになる。
①符号化文字集合
②符号化方式

符号化文字集合とは

符号文字集合を定め、かつその集合内の文字とビット組合せとを1対1に関係付けるあいまいでない規則の集合

文字符号化方式とは

符号化文字集合で文字に対応付けた非負整数値を、実際にコンピュータが利用できるデータ列(通常、バイト列)に変換する符号化方式。

上記の定義では中々頭に入って来にくいので下記のようなイメージをしてみるとわかりやすい
あ:U1
い:U2
う:U3
え:U4
お:U5
「あ」「い」「う」「え」「お」の各文字に一意のコードを割り当てた:これが符号化文字集合の考え方
そして、さらにこの集合を2種類の方式で符号化してみる。

符号化方式A
あ:U1:0x01
い:U2:0x02
う:U3:0x03
え:U4:0x04
お:U5:0x05

符号化方式B
あ:U1:0x01 0x10
い:U2:0x02 0x20
う:U3:0x03 0x30
え:U4:0x04 0x40
お:U5:0x05 0x50

文字集合と符号化方式がごっちゃになっていた

ちゃんと勉強する前は、Unicode, UTF-8, UTF-16が全て一緒くたになっていて混同していました。
Unicode文字集合を意味しており、その文字集合をどのようなバイト列で表すかを決めているのが
符号化方式であるUTF-8, UTF-16等ということがわかりました。

符号化方式の例

EUC-JP(JIS系の文字集合に対して)
Shift-JIS(JIS系の文字集合に対して)
UTF-8Unicodeに対して)
UTF-16Unicodeに対して)

参考サイト

blog.shibayu36.org
qiita.com