日本語における全角文字1文字分の入力を受け付けて、その一文字と当該文字コードを出力するというプログラム。言語研修中に不可解な問題が現れて、講師曰く、ASCIIを前提にしているみたいだから全角は考慮しなくていい、との事だったけれども、それはあたいにとっては気持ち悪かったからいろいろと考えてみたわけで。
で、今日やった応用的な言語での制御という部分で現れた制御を使ってみたらどうだろうと、研修に思い付いたので、それをコーディングしたらうまく回った次第。
てなわけで、久々のコード。全角部分の処理について。
ただし、Shift JISコードでの出力を前提にしているので。あと、入力された文字は全角文字を前提にしているので、はい。
------------------------------
#define U_MASK 0xff00 /* 上位バイトマスク */
#define D_MASK 0x00ff /* 下位バイトマスク */
unsigned short sh; /* scanfにて受け付けた文字(変換指定%2s)を格納する2B領域 */
~~~~~~~~~~~~~~~~~~~~~~~
int getSjis(unsigned short sh) {
unsigned char c[2]; /* 最終結果として出力するための1B領域配列 */
unsigned short wk; /* 各データ加工用2B領域 */
/* 上位バイト処理 */
wk = sh & D_MASK;
c[0] = (char)wk;
/* 下位バイト処理 */
wk = sh & U_MASK;
c[1] = (char)(wk >> 8);
printf("文字::%c%c////コード::%#x%x", c[0], c[1], c[0], c[1]);
return 0;
}
------------------------------------------------------------------------
これをSJISの'あ'(0x82a0)で追いかけてみると。
intel系アーキテクチャだとバイトが反転するので……
上位バイト処理
1010 0000 1000 0010 (shの値、0xa082)
0000 0000 1111 1111 (下位バイトマスク) &
--------------------------------------------------------------------
0000 0000 1000 0010 (wkに入力される値、0x82)
short →charキャストによって、
c[0] = 1000 0010
下位バイト処理
1010 0000 1000 0010 (shの値、0xa082)
1111 1111 0000 0000 (上位バイトマスク) &
-----------------------------------------------------------------------
1010 0000 0000 0000 (wkに入力される値、0xa000)
>>8 (1バイト右方向論理シフト)
----------------------------------------------------------------------------
0000 0000 1010 0000 (シフトされた結果、0xa0)
short →charキャストによって、
c[1] = 1010 0000
("%c%c", c[0], c[1])という表示扱いにすると、
"1000 0010 1010 0000"となって、イコール'あ'。
てなわけで、intelのアーキテクチャが持っているバイト情報が反転するという謎仕様に苦しめられた次第さ。
[0回]
PR