以下程序将结果显示为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 != '\0'; ++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;
}
唯一的区别是我们找到循环的合格条件的方式。为什么它不能与空字节检查一起使用?
答案 0 :(得分:2)
错误的代码:i != '\0'
检查索引是否为0。
for(i = 0; i != '\0'; ++i) {
应该在下面检查元素 str[i]
是否为空字符。
for(i = 0; str[i] != '\0'; ++i) {
存在其他问题unneeded increment,int
溢出(此处最好使用unsigned
),错误的x
检测-考虑“ 0x0x0x1”,导致-
或+
,char str[]
-> const char str[]
,...
答案 1 :(得分:1)
您的代码中存在一些问题:
将循环索引i
与'\0'
而不是str[i]
进行比较,从而导致循环立即终止,返回值为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] != '\0'; ++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;
}