我正在C编程语言书中练习,练习2-3要求我们编写一个函数htoi来将十六进制数转换为十进制数。
这是我写的代码,但是当它运行时,它总是显示我的十六进制数字是非法的。
请帮忙!
#include<stdio.h>
#define TRUE 1
#define FALSE 0
int htoi (char s[]);
int main() {
printf("The decimal number is %d\n", htoi("0x134"));
return 0;
}
int htoi (char s[]) {
int j; /* counter for the string */
int temp; /* temp number in between conversion */
int number; /* the converted number */
int ishex; /* if the number is a valid hexadecimal number */
char c;
number = 0;
temp = 0;
ishex = FALSE;
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
ishex = TRUE;
}
else {
ishex = FALSE;
printf("This is not valid hexadecimal number.\n");
return number = 0;
}
if (ishex == TRUE) {
for (j = 2; (c = s[j]) != EOF; ++j) {
if (c >= '0' && c <= '9')
temp = c - '0';
else if (c >= 'a' && c <= 'f')
temp = 10 + c - 'a';
else if (c >= 'A' && c <= 'F')
temp = 10 + c - 'A';
else {
printf("This is a illegal hexadecimal number.\n");
ishex = FALSE;
return 0;
}
number = number * 16 + temp;
}
}
return number;
}
答案 0 :(得分:0)
字符串是终止于第一个'\0'
字符的字符序列。这意味着"0x134"
以'\0'
字符值终止,而不是EOF
值。
您正在操作一系列字符,您期望以EOF
值终止这些字符,但这根本不可能。我稍后会解释原因...我现在只想说,字符串"0x134"
不包含EOF
值。
您的循环到达字符串终止'\0'
,该字符串不在0..9
,a..f
或A..F
范围内,因此此分支执行:
else {
printf("This is a illegal hexadecimal number.\n");
ishex = FALSE;
return 0;
}
也许你打算像这样写你的循环:
for (j = 2; (c = s[j]) != '\0'; ++j) {
/* SNIP */
}
我答应解释期待EOF
作为字符值存在的问题。假设unsigned char
为8位,getchar
可以返回256个字符值中的一个,并将它们作为正 unsigned char
值返回... 或它可以返回否定 int
值EOF
,对应于错误或文件结尾。
困惑?在一个空文件中,没有字符......但是如果你尝试从文件中读取一个字符,每次都会得到EOF
,尽管没有字符。因此,EOF
不是字符值。它是一个int
值,应该在之前将视为,然后尝试将值转换为字符,如下所示:
int c = getchar();
if (c == EOF) {
/* Here, c is NOT A CHARACTER VALUE! *
* It's more like an error code ... *
* XXX: Break or return or something */
}
else {
/* Here, c IS a character value, ... *
* so the following conversion is ok */
char ch = c;
}
另一方面,如果c是范围c >= '0' && c <= '9'
中的一个数字,0..9
将真实地评估......这是C标准的要求
然而,在任何情况下,都不需要c >= 'a' && c <= 'f'
和c >= 'A' && c <= 'F'
进行真实评估。它碰巧适用于您的系统,因为您使用的ASCII包含一个连续块中的所有小写字母,以及另一个连续块中的所有大写字母。 C不要求ASCII是字符集。
如果您希望此代码能够移植,您可能会考虑以下内容:
char alpha_digit[] = "aAbBcCdDeEfF";
if (c >= '0' && c <= '9') {
c -= '0';
}
else if (strchr(alpha_digit, c)) {
c = 10 + (strchr(alpha_digit, c) - alpha_digit) / 2;
}
else {
/* SNIP... XXX invalid digit */
}