#pragma twice

KAB-studio > プログラミング > #pragma twice > 206 Version 11.06 Unicode

#pragma twice 206 Version 11.06 Unicode

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

 Version 11.06
Unicode

今回は、文字コードのひとつ、 Unicode について紹介します
ゆにこーど?
そう。えーっと、文字コードについて簡単にまとめておくね。主な文字
コードには次のようなものがあります

ASCII : 日本語のない文字コード。 Unicode 以外はこれを含んでます。
Shift JIS : Windows で日本語を扱うときはこれ。
JIS : 普段は使わないけどメールを送るときにはこれに変換する。
EUC : Unix 用。ホームページの中にはこれで書かれてるものも。
Unicode : 2バイト変数で1文字を扱う。微妙な立場。
UTF-8 : 1〜3バイトで文字を表す。これからの本命?

いっぱいある……
って言っても今回はこれらには触れません
今回は Unicode なんだよね
そう。 Unicode そのものには次のような特徴があります

・2バイト変数で1つの文字を表現する。
・あらゆる国の文字を(一応)表現できる。
・ C++ では(一応)簡単に使用できる。
・ Windows では NT 、 2000 、 XP が対応している。

となっています。ひとつひとつ見ていくと

・2バイト変数で1つの文字を表現する。

あれ? Shift JIS も2バイトだったじゃない
あれは char がふたつだったでしょ。 Unicode の場合、 wchar_t ってい
う違う型を使います。で、これは

typedef unsigned short wchar_t;

ってなってます
 unsigned short と同じ、そっか、 short だから2バイトなんだ
このおかげで Unicode だとリードバイトとかトレイルバイトを気にしな
くていいんです
それいい! 変数の中にリードバイトとトレイルバイトの両方入ってるわ
けだから、区別しようがないんだもんね
そういうこと。これがまず Unicode のメリットのひとつ。次は

・あらゆる国の文字を(一応)表現できる。

何この〈一応〉って
 Unicode は2バイトだから、文字は何種類表せる?
 short だから……65535通りだね
そう。それだけあるから、日本と言わずありとあらゆる国のありとあらゆ
る文字を表せるんです
それってすごい……
んだけど、実は65535通りじゃ足りなかったんです
へ?
漢字みたいにすごく文字が多いものは全部表しきれなかったり、似た字が
ひとつにまとめられちゃったりしたんです
似た字がひとつにって……たとえば〈人〉と〈入〉とか?
あー、ううん、同じ国の文字はそうならなかったんだけど、日本の漢字と
中国の漢字で、見た目はちょっと違う、くらいのものが……
いっしょくた……?
そういうこと。これが Unicode が嫌われてる一番の理由かな
嫌われてるの?
微妙、だけどね。プログラミング言語によってはこれが標準のものもある

へー
さて次

・ C++ では(一応)簡単に使用できる。

また一応……
とりあえず、実際に使ってみます

void UseUnicode()
{
    wchar_t pwch[] = L"ABCあいう";
    OutputDebugStringW( pwch );
    // ABCあいう
}

お! 簡単にできたじゃない。えっと、違ってる部分は……まずさっきの
wchar_t を使ってるね
そう、 Unicode は char の代わりに wchar_t を使うから
次は……あ、 L って付いてる
そう。 "" で囲まれた文字列を Unicode 化する場合には、その先頭に L 
を付けます
付けないとダメ?
だめ。コンパイルエラーになっちゃうから。 Version 5.06 ( No.071 ) 
で〈 "" で囲まれた文字列は char のポインタになる〉って入ったでしょ
うん、言われた。あっ、そっか、それだと wchar_t と違っちゃうから
そういうこと。 L を付けると "" が wchar_t のポインタになるんです
そうしないと型が違っちゃうわけね
そういうこと。あともうひとつ違うところがあるんだけど
えーっと……あ! W が付いてる!
そう、いつもは OutputDebugString() なのに OutputDebugStringW() を
使ってます
これも Unicode 用、ってゆーか、引数が wchar_t のポインタを受けると
か?
そういうこと。だから、 Unicode を使う時にはこっちを使わなくちゃい
けないんです
めんどい……
ところが、実は面倒じゃないんです
へ?
 API には実は3種類あるんです。たとえばこの OutputDebugString() の
系統だと

OutputDebugString()
OutputDebugStringA()
OutputDebugStringW()

の3種類
ウソ。いつのまにそんなに……
まず OutputDebugStringW() 、この W が付いてるのは Unicode 用。逆に
OutputDebugStringA() が付いてるのは普通の Shift JIS 用
あれ? OutputDebugString() がそうなんじゃないの? じゃあなんなの
いったい
 OutputDebugString() は実は OutputDebugStringA() にも 
OutputDebugStringW() にもなるんです。実は OutputDebugString は、普段
は #define で OutputDebugStringA() に置き換えられているんです
ってことは、 OutputDebugString() を使ってると思ってたら実は
OutputDebugStringA() を使ってたってわけね
そういうこと。で

#define _Unicode

ってすると、 OutputDebugString() が今度は OutputDebugStringW() に
置き換わるようになるんです
おお! つまり、 OutputDebugString() を使ってれば、いつでも変えら
れるってわけね
そういうこと。ちなみにこういうふうに切り替えるために使うマクロにつ
いては Version 6.06 ( No.106 ) を参照ってことで
質問!
はい火美ちゃん
 W とか A ってなんの略?
 W は Wide 。2バイトで1文字を表すから〈ワイド〉ってことでそう
なってるみたい。 wchar_t の w もそうだし。 A は ASCII の A 
そっちは簡単な理由ね……
で、話を戻して。実はこのどっちも使える機能は、 wchat_t にも L にも
あるんです。それを使って書いてみるとこんな感じ

void UseUnicode()
{
    TCHAR pwch[] = _T( "ABCあいう" );
    OutputDebugString( pwch );
}

えっと、 wchar_t が TCHAR に、 L が _T() に……あ! この _T って
よく見かける!
サンプルコードとかによく使われてるかな。こうしておけば、 _Unicode 
を #define するだけで Unicode が使えます
へー
ついでに書くとランタイムにも同じようなのがあって

strcpy : 標準。一応 ASCII 専用。
wcscpy : Unicode 専用。
_mbscpy : 一応 Shift JIS 用。
_tcscpy : _Unicode が #define されてたら wcscpy 。
     そうでないなら _mbscpy 。

つまり、さっきの例で言えば _tcscpy を使うべきってことね
そういうこと。そうすれば自動的に切り替えてくれるからね
質問!
はい火美ちゃん
 T ってなんの略?
たぶん Text の T 。 _T は _TEXT って書くこともできるから
もうひとつ質問! なんでこれ、今まで教えてくんなかったの?
色々理由があって、まずはこれ

・ Windows では NT 、 2000 、 XP が対応している。

さっき言ってたのの最後のね
これはつまり、 Windows95 とか Windows98 とか WindowsMe では使えな
いってことなんです
げげ! 使えないってどういうこと??
 W が付いた API 、あることはあるんだけど中身が入ってないってこと
それじゃダメね……
だから実際には使えないのも同じ。それに、一番最初から教えるのにこう
いうよく分からないのは含めたくなかったからね
確かに _T とかいっぱいあるとわかんないね……
というか……まぁ僕の知ってる限り、実際に Unicode 版を使ってるのっ
て知らない
便利そうなのに
 C++ ではなじみないから、難しいかも。さて、最後に

    wchar_t pwch[] = L"ABCあいう";

これが、メモリ上ではどう入ってるのか確認します。ブレークポイント付
けてアドレス調べて、メモリ直接見てください
いつものパターンね
そうすると

A     B     C     あ    い    う    \0
41 00 42 00 43 00 42 30 44 30 46 30 00 00 

ってなってます
あ、そっか、2バイトずつってことは、 ASCII の A とか B とかもそう
入ってるんだ。……あれ?

A
41 00

ってこと? なんか変くない?
 Version 4.07 ( No.057 ) で説明したバイトオーダーがあるから
げ! こんなとこにもあの面倒なのが!
で、バイトオーダーって OS 毎に違うんだよね。その辺もややこしいから 
とりあえず使わない方がいいかも

/*
    Preview Next Story!
*/
なんかすごく便利そうだったのに……
これは Unicode が悪いって言うより C++ が悪いかな
え? どうして?
他の言語だと Unicode が標準っていうのもあるから
え〜? ずるい〜
というわけで次回
< Version 11.07 1バイト文字と2バイト文字 >
につづく!
まぁいいことばかりじゃないんだよね、これが……
そなの?
文字コード関係は、はまると怖いよ、ほんと……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。