[제나플러스] 일본어 홈피제작시 문자열 자르는 팁
본문
Shift_JIS
Shift_JISの場合,全角文字は2バイトで表されることになっています.
JIS
で使われていなかったビット列の部分に文字をシフトしてきたコードです. JISコードのように,エスケープシーケンスは必要ありませんが,
1バイト目が0x81-0x9F,0xE0-0xFC,2バイト目が0x40-0x7E,0x80-0xFCの範囲しか使えないため,表現できる文字
は,11000文字程度になります.
先ほどの文字列をShift_JISで表現すると「61 62 63 82 A0 82 A2 82 A4 31 32 33」の12バイトになります.
文字数のカウント
1バイトずつ読み込み,0x81-0x9F,0xE0-0xFCの範囲の文字があるかチェックする必要があります.次に,文字数カウントのソースを載せておきます.適当に書いただけなのでどこまで正確か分かりません.ただ,流れは分かると思います.
int count_Shift_JIS(const unsigned char *string)
{
int len = 0;
while(*string){
if(*string < 0x1f || *string == 0x7f){
;// 制御文字
}else if((0x81 <= *string && *string <= 0x9F) || (0xE0 <= *string && *string <= 0xFC)){
// 2バイト文字
++string;
if((0x40 <= *string && *string <= 0x7E) || (0x80 <= *string && *string <= 0xFC))
++len;
else
break; // 不明な文字
}else{
// 1バイト文字
if(0x80 < *string)
;// 半角カナ
++len;
}
++string;
}
return len;
}
補足
Shift_JISの場合,一部のプログラム(perlなど)でダメ文字問題が発生することがあります.これは,2バイト文字の2バイト目の部分に0x5Cが使われていることに原因があります.
Shift_JIS
では,2バイト目に0x40-0x7Eと0x80-0xFCが許可されています.しかし,この中の0x5Cはいわゆるエスケープ文字(\)を表していま
す.このエスケープ文字は次のバイトと組み合わせて解釈される文字です(2バイトを1バイトとして解釈するわけです).そのため,本来文字として正しいは
ずの1バイト目と2バイト目の組み合わせがずれてしまい,
1バイト目と次の文字の1バイト目(本来の2バイト目0x5Cが消えてしまう),次の文字の2バイト目とさらに次の1バイト目と順にずれてしまいます.
(本来,プログラム側が文字コードを認識して動作すべきだとは思いますが,)このような文字が来る場合,0x5C 0x5Cの組み合わせは0x5Cとして解釈されることを利用しあらかじめ0x5Cを追加しておくことが必要になります.
例えば,"予定表"の場合,1文字目と3文字目はダメ文字です.そのため,"予\定表\"のようにダメ文字の後に問題のエスケープ文字(0x5C)を追加することで正しく表示することができます.
ダメ文字リスト:―ソЫⅨ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭偆砡
良く使われてしまうダメ文字は"ソ,十,能,表,予"あたりでしょうか.
EUC-JP
原則として日本語を2バイトとして表現した方法ですが,亜種として一部の拡張文字を3バイトで表現するコードもあります.日本語文字は,1バイト目,2バイト目共に0x80-0xFFの範囲にあることが特徴です.
3バイト必要とするのは,第4水準文字であり,通常使われることはないと思います.先ほどの文字列をEUCで表現すると「61 62 63 A4 A2 A4 A4 A4 A6 31 32 33」の12バイトになります.
文字数のカウント
1バイトずつ読み込み,0x80-0xFFの範囲の文字があるかチェックする必要があります.次に,文字数カウントのソースを載せておきます.適当に書いただけなのでどこまで正確か分かりません.ただ,流れは分かると思います.
int count_EUC(const unsigned char *string)
{
int len = 0;
while(*string){
if(*string < 0x1f || *string == 0x7f){
;// 制御コード
}else if(*string == 0x8E){
if(0xA1 <= *++string && *string <= 0xFE)
// 半角カナ
++len;
else
break; // 不明な文字
}else if(*string == 0x8F){
// 3バイト文字
if((0xA1 <= *++string && *string <= 0xFE) &&
(0xA1 <= *++string && *string <= 0xFE))
++len;
else
break; // 不明な文字
}else if(0xA1 <= *string && *string <= 0xFE){
// 2バイト文字
if(0xA1 <= *++string && *string <= 0xFE)
++len;
else
break; // 不明な文字
}else{
// 1バイト文字
++len;
}
++string;
}
return len;
}
Unicode(UTF-8)
ASCII文字は1バイト,それ以外の文字を2-6バイトで表現した方法です.日本語文字は大半が3バイトで
表現されます.先ほどの文字列をUTF-8で表現すると「61 62 63 E3 81 82 E3 81 84 E3 81 86 31 32
33」の15バイトになります.
文字数のカウント
1バイト目を読めば何バイトの文字か分かるため非常にカウントが楽です.
1バイト目が0xxxxxxxの場合,1バイト文字でASCIIコードと同じです.
10xxxxxxの場合,他のマルチバイト文字の続き文字になります.
110xxxxxの場合,2バイト文字の先頭になります.
以
下同様に,1110xxxxの場合は3バイト文字,11110xxxの場合は4バイト文字,
111110xxの場合は5バイト文字1111110xの場合は6バイト文字の先頭になりますが,実際には4バイト文字までしか定義されていないた
め,0xf8以上の文字が出た場合,エラーにしてしまっても構わないかもしれません.
一応定義上は存在するようです.
int count_UTF8(const unsigned char *string)
{
int len = 0;
while(*string){
if(*string < 0x1f || *string == 0x7f){
// 制御コード
}else if(*string <= 0x7f){
++len; // 1バイト文字
}else if(*string <= 0xbf){
; // 文字の続き
}else if(*string <= 0xdf){
++len; // 2バイト文字
}else if(*string <= 0xef){
++len; // 3バイト文字
}else if(*string <= 0xf7){
++len; // 4バイト文字
}else if(*string <= 0xfb){
++len; // 5バイト文字
}else if(*string <= 0xfd){
++len; // 6バイト文字
}else{
; // 使われていない範囲
}
++string;
}
return len;
}
관련링크
댓글목록 0
등록된 댓글이 없습니다.