K&R演習[2-3]

課題

16進数の文字列(0xあるいは0Xが付いているものも含めて)をそれと同値な整数値へ変換するhtoi(s)を書け。

回答

#include <stdio.h>
#include <string.h>

int htoi(char *str);

/**
 * @fn      Main
 * @brief
 * @param
 * @return
 * @detail
 */
int main(void)
{
    int i;
    char str[30];

    sprintf(str, "0x453");  i = htoi(str);  printf("%s, %5x, %10d\n", str, i, i);
    sprintf(str, "x453");   i = htoi(str);  printf("%s, %5x, %10d\n", str, i, i);
    sprintf(str, "453");    i = htoi(str);  printf("%s, %5x, %10d\n", str, i, i);
}


/**
 * @fn      htoi
 * @brief   
 * @param   
 * @return  
 * @detail  
 */

int htoi(char *str)
{
    char *start;
    int c, i = 0, ret = 0;

    start = str;                    // 開始位置(暫定)
    if (*str == '0') {              // 先頭が'0'で
        if ((*(str + 1) == 'x') ||  // 2文字目が'x'か
            (*(str + 1) == 'X')) {  // 'X'なら
            start = str + 2;        // 0xまたは0Xの次から開始する
        }
    }

    // 文字列終端まで置き換える
    while ((c = *(start + i)) != '\0') {
        if          (('0' <= c) && (c <= '9')) {    ret = ret * 16 + c - '0';   // 0~9
        } else if   (('a' <= c) && (c <= 'f')) {    ret = ret * 16 + c - 'a';   // a~f
        } else if   (('A' <= c) && (c <= 'F')) {    ret = ret * 16 + c - 'A';   // A~f
        } else { return -1; // エラー
        }
        i++;
    }
    return ret;
}

実行結果

0x453,   453,       1107
x453, ffffffff,         -1
453,   453,       1107