我在做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'
处终止的字符序列特点。这意味着 "0x134"
以 '\0'
结束字符值,不是 EOF
值(value)。
您正在操作一系列您希望以 EOF
终止的字符值,但这根本不可能。稍后我会解释为什么……现在我只想说,字符串 "0x134"
不包含 EOF
值(value)。
您的循环到达字符串终止 '\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 个字符值之一,并将它们作为 positive unsigned char
返回值...OR 它可以返回负数 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 >= '0' && c <= '9'
当 c 是 0..9
范围内的数字之一时,将如实评估...这是C标准的要求
都不是c >= 'a' && c <= 'f'
也不c >= 'A' && c <= 'F'
但是,在任何情况下都需要如实评价。它恰好适用于您的系统,因为您使用的 ASCII 包含一个连续 block 中的所有小写字母,以及另一个连续 block 中的所有大写字母。 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 */
}
关于C中十六进制数转十进制数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33685190/