私の失礼な英語で説明してみてください:(
私のコード(すべての入力が正しいと仮定します。防御的なプログラミングは避けてください)
#include <stdio.h>
enum { SZ = 11 };
unsigned int htoi(const char *s);
int main()
{
char buff[SZ]; //Max 11 char: 0x XX XX XX XX '\0' (2 + 8 + 1)
while(fscanf(stdin, "%s", buff) != EOF)
printf("%X\n", htoi(buff) );
return 0;
}
unsigned int htoi(const char *s)
{
unsigned int i, r = 0;
for(i = (s[1] == 'x') ? 2 : 0; s[i] != '\0'; i++)
r = ( r << 4 ) + ( (s[i] > '9') ? 0x9 : 0x0 ) + ( s[i] & 0xF );
return r;
}
まず、r = 0を割り当てます。次に、for-bucleを開始するときに、インデックス変数iにinit値を指定します。文字列が0x形式であるかどうかを確認する必要があります。位置1をチェックするだけで、入力文字列を0x形式で処理しているかどうかを知ることができます。
これで、最初の正しい文字を指すインデックスができました。反復ごとに、4ビットを左に移動します。4つのゼロを取得します。新しい16進数を追加するための完璧なギャップ!例:
Input: 0xBE1234
Is s[1] == 'x' ? true then i = 2;
r = 0;
iter 1: r = 0x0; r = 0x0; r = 0xB;
iter 2: r = 0xB; r = 0xB0; r = 0xBE;
iter 3: r = 0xBE; r = 0xBE0; r = 0xBE1;
iter 4: r = 0xBE1; r = 0xBE10; r = 0xBE12;
iter 5: r = 0xBE12; r = 0xBE120; r = 0xBE123;
iter 6: r = 0xBE123; r = 0xBE1230; r = 0xBE1234
これは少し複雑かもしれません:
r = ( r << 4 ) + ( (s[i] > '9') ? 0x9 : 0x0 ) + ( s[i] & 0xF );
まず、16ごとの乗算と同じですが、より効率的な4ビットを置き換えます。次に、「9」より大きいASCII文字があるかどうかを調べます。それが本当なら、私たちはA、B、C、D、E、Fまたはa、b、c、d、e、fで作業しています。正しい入力があると想定していることを忘れないでください。では、ASCIIテーブルを見てみましょう。
A = 0100 0001 - a = 0110 0001
...
F = 0100 0110 - f = 0110 0110
しかし、私たちはこのようなものが欲しいです:
A = 0000 1010 - a = 0000 1010
...
F = 0000 1111 - f = 0000 1111
どうすればいいですか?置換後、マスクs[i]と0xFを使用して4つの最上位ビットをクリアします。
s[2] == 'B' == 0100 0010
s[2] & 0xF == 0000 0010
整数値に適応するために9を追加します({'A' ...'F'、'a' ...'f'}のs[i]の場合のみ)
s[2] & 0xF + 0x9 = 0000 0010 + 0000 1001 = 0000 1011 (0xB)
最後に、置き換えられたr値に追加し、rに割り当てます。2回目の反復の実行シーケンス(s [3]):
r == 0xB, s[3] == 'E' == 0100 0101 (start iter 2)
(r << 4) == 0xB0, s[3] == 'E' == 0100 0101 (displacement r << 4 )
(r << 4) == 0xB0, (s[3] & 0xF + 0x9) == 0000 1110 == 0xE (clear most significant bits of s[3] and add 0x9)
r = (r << 4) + ( s[3] & 0xF + 0x9 ) == 0xBE == 1011 1110 (add all and assign to r)
s [4]のような数字があるとどうなりますか?
s[4] == '1' == 0011 0001
s[4] & 0xF == 0000 0001
変位rの4つの位置、0(なし)を追加し、論理演算s [i]&0xFの結果を追加し、最後にrに割り当てます。
r == 0xBE, s[4] == '1' == 0011 0001 (start iter 3)
(r << 4) == 0xBE0, s[4] == '1' == 0011 0001 (displacement r << 4 )
(r << 4) == 0xBE0, (s[4] & 0xF + 0x0) == 0000 0001 (clear most significant bits of s[4] and add 0)
r = (r << 4) + s[4] & 0xF == 0xBE1 == 1011 1110 0001 (add all and assign)
4つのゼロのギャップで重要度の低いビットを追加しているため、桁ビットをメッシュしないように4をシフトすることを忘れないでください。
PD:申し訳ありませんが、より良い説明のために英語を上達させることを約束します。