#pragma twice

KAB-studio > プログラミング > #pragma twice > 203 Version 11.03 Shift JIS

#pragma twice 203 Version 11.03 Shift JIS

前のページへ 表紙・目次へ 次のページへ

 Version 11.03
Shift JIS

「前回は、ファイルパスからファイル名だけ取り出すっていうのをしてみま
した」
『と思ったら』

    char ch[] = "C:\\Test\\ソフト.txt";

『が』

フト.txt

『になっちゃったのよねー。なんで?』
「これは、日本語の文字列が特殊だから。日本語を処理することを考える
と、実は文字列処理はとっても難しくなります」
『げげ!』
「でも、避けては通れない部分だから、まず最初に解決しておくことにしま
す」
『……そんなに難しい?』
「ややこしいんだよね、とにかく。苦手な人もかなりいるから、すぐわから
なくても大丈夫だからね」
『フツーのプログラマーも難しい分野なのね……』
「ではさっそくいきます。まず、さっきの文字列」

    char ch[] = "C:\\Test\\ソフト.txt";

「これが、メモリ上にはどう並んでいるかメモリウィンドウで見てみます」

C  :  \  T  e  s  t  \  ソ    フ    ト    .  t  x  t  \0
43 3A 5C 54 65 73 74 5C 83 5C 83 74 83 67 2E 74 78 74 00

『あれ? ソフトのところ……』
「そう、ふたつずつになってるでしょ。日本語の文字は」

ソ

「だったら」

83 5C

「っていう2文字分、つまり2バイトで表現してるんです」
『なんで2文字分?』
「まずはそこからだね。コンピューターはアメリカでできたものだから、文
字って言ったらもちろんアルファベット」
『そうだね』
「アルファベットって文字数少ないから1バイトで……1バイトで表現でき
る数ってやったっけ」
『えっと、数字だと、 char は -128 〜 127 だよね』
「 unsigned だと?」
『あー、えーっと、 0 〜 255 だったね、 Version 4.06 ( No.056 ) の時
に教わったけど』
「ってことは、1バイトだと256文字分表現できるってこと」
『 C が 0x43 、 : が 0x3A 、みたいにってことだよね』
「そうそう。でも256文字じゃ漢字は」
『あ! そっか、漢字なんてすんごく数あるもんね、入りきらないんだ』
「だから、日本語の文字は何バイトかくっつけて1文字を表現するしかなく
て、だから 0x83 0x5C でソを表すってなったわけ」
『なるほどねー』
「ただし!」
『ただし?』
「同じソでも」

0x83 0x5C
0x30 0xBD
0xA5 0xBD
0x25 0x3D

「って色々な数字で表されるんです」
『ど、どういうこと?』
「ソを表示するためには」

[「ソ」を表す数字]
    ↓
[変換表で数字を「ソ」に]
    ↓
[フォントの「ソ」を使って画面に表示]

「っていう段階を踏みます。ところが、真ん中の」

[変換表で数字を「ソ」に]

「がいっぱいあるんです」
『げ!』
「ある変換表は 0x83 0x5C をソに、またある変換表は 0x30 0xBD をソに変
換するっていう具合に。こういう変換表を【文字コード表】って言います」
『あー、インターネットしてるといっぱいあるよね、 EUC とかシフト JIS 
とか』
「そうそう、それそれ。で、ウィンドウズでは Shift JIS っていう文字
コードが使われてます。だから」

[「ソ」を表す数字 0x83 0x5C ]
    ↓
[ Shift JIS 文字コード表で数字を「ソ」に]
    ↓
[フォントの「ソ」を使って画面に表示]

「っていう手順で表示されます。インターネットとかの他の文字コードの場
合は」

[ 他の文字コードの「ソ」を表す数字 0x30 0xBD ]
    ↓
[ 他の文字コードから Shift JIS に変換 ]
    ↓
[「ソ」を表す数字 0x83 0x5C ]
    ↓
[ Shift JIS 文字コード表で数字を「ソ」に]
    ↓
[フォントの「ソ」を使って画面に表示]

「って感じになります」
『一度 Shift JIS ってゆーのに変換してから表示するわけね。あれ? こ
の Shift JIS と、さっきあたしが言ったシフト JIS って同じもの?』
「そう、おなじもの。この Shift JIS =シフト JIS がウィンドウズで使わ
れてる日本語の文字コードだから、インターネットのとか考える必要がなけ
ればこの Shift JIS のことだけ考えればいいから」
『普通にプログラムしてればそれでいいってことよね』
「今のところはね」
『?』
「本当は Shift JIS じゃなくて MS932 とか Windows-31J とか言わなく
ちゃいけないんだけど……ん、今のは忘れて」
『むー、なんか気になる……』
「もういちどまとめると、ウィンドウズでは日本語の文字は Shift JIS 
っていうのを使ってて、ソなら」

[「ソ」を表す数字 0x83 0x5C ]
    ↓
[ Shift JIS 文字コード表で数字を「ソ」に]
    ↓
[フォントの「ソ」を使って画面に表示]

「って感じに変換されます」
『うん、そこまでは大丈夫』
「じゃあ、前回の問題について。というより見ればわかると思うけど」

\  ソ   
5C 83 5C

『あ! なに、 \ は 0x5C 、ソは 0x83 0x5C 、ってことはその2文字目が
\ と同じなんじゃない!』
「そうなんです。だから普通に \ を探していくと、このソの2バイト目と
一致しちゃうんです」
『……よーするに、それが \ じゃなくて、ソの2バイト目ってことがわか
ればいいんだ』
「そういうこと。この Shift JIS の1バイト目を【リードバイト】、2バ
イト目を【トレイルバイト】っていいます」
『りーどばいとととれいるばいと?』
「英語で書くと Lead Byte と Trail Byte 。 lead は〈先行する〉、 
trail は〈ついていく〉って意味があります」
『よーするに前と後ろってことね』
「そゆこと」
『だから、 \ がみつかったときにそれがトレイルバイトかどうかが判れば
いい、ってことだよね。……でも、ピンポイントで見たら、わかんないよ
ね』
「そう、だから前後関係で見ないといけないんです」
『つまり、1バイト前がリードバイトかどうか調べるってこと?』
「まずはそう」
『まずは?』
「そう、まずは、ね。このリードバイトは、 0x81 〜 0x9F と
0xE0 〜 0xFC の間の値って決まってます」
『つまりその間かどうか見ればリードバイトかどうか』
「わからないんです」
『へっ?』
「なぜかっていうと、トレイルバイトは 0x40 〜 0x7E と 0x80 〜 0xFC の
間の値って決まってるからです」
『……重なってる?』
「そういうこと。プログラムで試してみようか」

void OutputLeadAndTrail()
{
    char ch[] = "==";
    TRACE( "%s\n%s\n", ch, &( ch[1] ) );
}

「==は Shift JIS 、つまりいわゆる全角文字で書いてください」
『えーっと、まず普通に表示して、次に……あ、1バイト先から出力してる
んだね』
「そう。で、これを実行すると」

==
=

『げ! なに、また同じ=?』
「 ch をメモリウィンドウで見ると」

=    =    \0
81 81 81 81 00

「ってなってるんです」
『……ってことは、ずらすと……』

=       \0
81 81 81 00

『ってこと??? これじゃリードバイトかトレイルバイトかわかんない
じゃん!』
「というわけで次回に続く!」

/*
    Preview Next Story!
*/
『あーもうなんだか混乱してきた!!』
「こういうのはメモリを見たり紙に書いたりするといいかも」
『今みたいに?』
「頭の中だけで考えると混乱するだけだから」
『へー』
「というわけで次回」
< Version 11.04 文字種の判定 >
『につづく!』
「だから、 VC って初心者向けかな」
『なんの話?』
「こっちの話」
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。