K&Rを読もう(27) 問題2-3 htoi

16進文字列を数値に変換するhtoiを実装せよ。0xのある場合も考慮しなければならない。という問題。

GCC拡張のcase 'a' ... 'f'を使ってみた。

#include <stdio.h>
#include <stdlib.h>

int htoi(char *s)
{
    unsigned int i = 0;
    int tmp;
    
    if (*s == '0' && *(s + 1) == 'x')
        s += 2;

    for (; *s != '\0'; s++) {
        tmp = i * 16 + *s;
        switch(*s) {
            default: return (int) i;
            case 'a' ... 'f' : i = tmp -'a' + 10; break;
            case 'A' ... 'F' : i = tmp -'A' + 10; break;
            case '0' ... '9' : i = tmp -'0';      break;
        }
    }
    return (int) i;
}

int main(void)
{
    printf("%x\n", htoi(""));
    printf("%X\n", htoi("0xaF09です。")); /* AF09 */
    printf("%X\n", htoi("0AXXです。"));   /* A */

    exit(EXIT_SUCCESS);
}
  • case拡張便利!!ドットは3つ。
  • "0x"の処理をどうするか結構迷った。現在のポインタに文字があれば次の値に文字、又は'\0'がある事は確実なので、配列の長さをチェックしなくてもセグメントエラーは出ない。
  • 最初、+10を忘れたので変な値になった。
  • tmpを消したいけど、うまく消せない。condがホシイ・・・。