http://ja.wikipedia.org/wiki/%E5%85%A8% ... A%E8%A7%92
全角は漢字を含む2バイト文字、半角は英数字記号とカタカナの1バイト文字という意味で使っていましたので、ここでの呼び方は2バイト文字と1バイト文字に統一します。
さて、文字列に中身に挑む第2弾です。
先程の文字列は1バイト文字の集まりでした。
1バイトで表せるのは0x00~0xFFの256種の文字だけですよね。
でも漢字とか普通に扱ってません?
漢字の文字種なんて何千種類もありますよ。足りませんよね?
って事で、その秘密がシフトJISです。
シフトJISは、英数字記号とカタカナは1バイトで漢字などの全角文字は2バイトで文字を表現しましょう。って文字コードの規格です。これ以外にも文字コードの規格はEUCやらUTF-8やら色々あるのですが、今回関係あるのはWindowsのC言語で主につかわれるシフトJISに付いて解説します。
「シフトJIS」
http://ja.wikipedia.org/wiki/Shift_JIS
で、問題なのは1バイト文字なのか2バイト文字なのかの判断です。
なんせ、そのままだと1バイト文字コードが並んでいるだけにしか見えませんので、文字コードを見て1バイト文字と2バイト文字を自動判断出来ないといけません。
シフトJISはwikipediaに書かれたとおり、1バイト文字で使わない文字コードを使って2バイト文字文字に拡張するって仕組みを持っています。つまり1バイト目がある特定の文字コードの場合は続けて2バイトも文字コードとして扱うって仕組みです。
これは、1バイト目が0x81~0x9Fか0xE0~0xFFである場合は2バイト文字として扱うことで漢字までを扱えるような文字コードに拡張しようって裏技的なテクニックなんですね。
「シフトJIS キャラクタコード表」を見てもらえば漢字の1バイト目が特徴的なのが分かると思います。
http://www.tamasoft.co.jp/ja/general-info/sjis2.html
今回のウィンドウ・システムでは、関数で1バイト目が0x81~0x9Fか0xE0~0xFFで判断して2バイト文字か1バイト文字かを判断します。
これは、メッセージ出力で一文字づつ出力する必要があるので2バイト文字か1バイト文字かを判断しないと表示できないためです。
じゃあ、またまたテストコードです。
#include
#include
#include
#include
void hexDump(char *str)
{
int i;
unsigned char *bstr = (unsigned char *)str;
// 文字列をそのまま出力
printf( "%s", str );
// 文字列を16進ダンプ
for( i=0 ; str[i]!='\0' ; i++ ) {
// 2バイトコード文字コード?
if( ( 0x81<=bstr[i] && bstr[i]<=0x9F ) ||
( 0xE0<=bstr[i] && bstr[i]<=0xFF ) ) {
// 2バイト文字コード
printf( "%02X%02X ", bstr[i],bstr[i+1] );
i++;//1バイト余分にすすませる。
} else {
// 1バイト文字コード
printf( "%02X ", bstr[i] );
}
}
printf( "\n" );
}
int main()
{
int a;
char *str1="abc\n";
char *str2="abc\n";
char *str3="アイウアイウ\n";
// そのまま16進ダンプ
hexDump(str1);
hexDump(str2);
hexDump(str3);
(a=-999) + (rand()%1999);
_getch();
return 0;
}
次回は、禁則処理とプロポーショナルフォントです。