#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のトップページをご覧ください。