使用C将十六进制字符串常量转换为十进制值

Conversion of hexadecimal string constant to decimal value using C

以下程序给出的结果为 0,而不是十六进制字符串常量的预期十进制等价物。

#include <stdio.h>

int my_htoi(char[]);

int main(void) {
    printf("%d", my_htoi("0xABC"));
    return 0;
}

int my_htoi(char str[]) {
    int i, num = 0;
    for (i = 0; i != '[=10=]'; ++i) {
        if (str[i+1] == 'x' || str[i+1] == 'X') {
            i = i + 1;
            continue;
        }
        if (str[i] >= '0' && str[i] <= '9') {
            num = num * 16 + (str[i] - '0');
        } else if (str[i] >= 'a' && str[i] <= 'f') {
            num = num * 16 + (str[i] - 'a' + 10);
        } else if (str[i] >= 'A' && str[i] <= 'F') {
            num = num * 16 + (str[i] - 'A' + 10);
        }
    }
    return num;
}

虽然以下程序运行良好并输出十六进制字符串常量的正确十进制等价物。

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

int my_htoi(char[]);

int main(void) {
    printf("%d", my_htoi("0xABC"));
    return 0;
}

int my_htoi(char str[]) {
    int i, num = 0;
    for (i = 0; i < strlen(str); ++i) {
        if (str[i+1] == 'x' || str[i+1] == 'X') {
            i = i + 1;
            continue;
        }
        if (str[i] >= '0' && str[i] <= '9') {
            num = num * 16 + (str[i] - '0');
        } else if (str[i] >= 'a' && str[i] <= 'f') {
            num = num * 16 + (str[i] - 'a' + 10);
        } else if (str[i] >= 'A' && str[i] <= 'F') {
            num = num * 16 + (str[i] - 'A' + 10);
        }
    }
    return num;
}

唯一的区别在于我们找到循环的合格条件的方式。为什么它不适用于空字节检查?

错误代码:i != '[=12=]' 检查 index 是否为 0。

for(i = 0; i != '[=10=]'; ++i) {

应该是下面检查元素 str[i]是否是空字符.

for(i = 0; str[i] != '[=11=]'; ++i) {

存在其他问题 int 溢出(最好在此处使用 unsigned)、错误 x 检测 - 考虑“0x0x0x1”,领先 -+char str[] --> const char str[]、...

您的代码中存在一些问题:

  • 循环索引 i'[=12=]' 而不是 str[i] 进行比较,导致循环立即终止,return 值为 0.

  • x 的测试不正确:它会导致 "1x2" 转换为 2 而不是 1

  • 您接受 f 以外的字母并将它们转换为数字。该函数应该在第一个不是十六进制数字的字符处停止解析。

这是更正后的版本:

#include <stdio.h>

int my_htoi(const char[]);

int main(void) {
    printf("%d", my_htoi("0xABC"));
    return 0;
}

int my_htoi(const char str[]) {
    int i = 0, num = 0;
    if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
        i += 2;
    for (; str[i] != '[=10=]'; ++i) {
        if (str[i] >= '0' && str[i] <= '9') {
            num = num * 16 + (str[i] - '0');
        } else if (str[i] >= 'a' && str[i] <= 'f') {
            num = num * 16 + (str[i] - 'a' + 10);
        } else if (str[i] >= 'A' && str[i] <= 'F') {
            num = num * 16 + (str[i] - 'A' + 10);
        } else {
            break;
        }
    }
    return num;
}