2-3 htoi.c

依存多い…
もちろん、まっとうに使うときはtolower()やisxdigit()を使いましょう。

/*
 * P57 演習2-3
 *   16進数の文字列(0xあるいは0Xが付いているものも含めて)を
 *   それと同値な整数値へ変換する関数htoi(s)を書け。許される
 *   文字は0から9とaからfおよびAからFである。
 *
 *         2007/06/23 arikui
 */

int lower(char c){
    if (c >= 'A' && c <= 'Z') return c + 'a' - 'A';
        else return c;
}


int xdigit_p(char chr){
    int c = lower(chr);
    if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z'))
        return 1;
    return 0;
}


int c2x(char chr){
    int c = lower(chr), x = chr;
    if (c >= '0' && c <= '9'){
        x = c - '0';
    }else if (c >= 'a' && c <= 'z'){
        x = c - 'a' + 10;
    }
    return x;
}


int htoi(char *s){
    int i = 0, n = 0;
    
    for(; s[i] != '\0'; ++i){
        if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n')
            break;
    }
    
    if (!xdigit_p(s[i])) return 0;
    
    if (s[i] == '0'){
        ++i;
        if (lower(s[i]) == 'x') ++i;
    }
    
    for(; s[i] != '\0'; ++i){
        if (s[i] != '0') break;
    }
    
    for(; s[i] != '\0'; ++i){
        n *= 16;
        n += c2x(s[i]);
    }
    
    return n;
}


//Test Driver
#include<stdio.h>

int main(void){
    int i;
    char *test_data[] = {
        "3A", "FF", "00FF",
        "0x00FF", "0X00FF",
        NULL
    };
    
    for(i = 0; test_data[i] != NULL; ++i)
        printf("%10s -> %d\n", test_data[i], htoi(test_data[i]));
    
    return 0;
}