/* hexadecimal to decimal conversion */
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
char hex[17];
long long decimal;
int i , val, len;
decimal = 0;
// Input hexadecimal number from user
printf("Enter any hexadecimal number: ");
gets(hex);
//Find the length of total number of hex digit
len = strlen(hex);
len--;
for(i=0; hex[i]!='\0'; i++)
{
// Find the decimal representation of hex[i]
if(hex[i]>='0' && hex[i]<='9')
{
val = hex[i] - 48;
}
else if(hex[i]>='a' && hex[i]<='f')
{
val = hex[i] - 97 + 10;
}
else if(hex[i]>='A' && hex[i]<='F')
{
val = hex[i] - 65 + 10;
}
decimal += val * pow(16, len);
len--;
}
printf("Hexadecimal number = %s\n", hex);
printf("Decimal number = %lld", decimal);
return 0;
}
在上面的程序中,当我使用scanf而不是gets时,它没有给出结果。为什么?我使用了scanf("%x",hex);
。请你解释我decimal += val * pow(16, len);
。非常感谢你。
答案 0 :(得分:2)
因为如果您使用scanf()
,它会为您执行字符串转换,这就是它的全部内容。
unsigned int x;
if(scanf("%x", &x) == 1)
printf("you entered %d (hex 0x%x)\n", x, x);
您不能将%x
指针组合到字符数组,它需要指向无符号整数的指针。这当然在manual page中有详细记载。
此外,在这里使用pow()
似乎过多,只需将之前的数字乘以添加每个新数字:
unsigned int parsehex(const char *s)
{
unsigned int x = 0;
const char *digits = "0123456789abcdef";
const char *p;
while(*s && (p = strchr(digits, tolower(*s++))) != NULL)
{
x *= 16;
x += (unsigned int) (p - digits);
}
return x;
}
这有点“重”&#34; (使用strchr()
)而不是代码,但更短,因此更容易验证。如果它过于表现至关重要,我会考虑调查一下。
答案 1 :(得分:2)
scanf("%x",hex);
应该是
scanf("%s",hex);
当你读为整数时,你不能做hex [i]。
decimal += val * pow(16, len); represents decimal = decimal + (val * pow(16, len));
希望这能回答你的问题
答案 2 :(得分:1)
scanf("%x"...)
为您执行转换为整数。因此,您希望将结果存入decimal
:
scanf("%x", &decimal);
for循环的每次迭代都会将数字的半字节(4位)生成val
。 val * pow(16, len);
(in)有效地将半字节移动到正确的位置。但是,此代码使用浮点数学来完成此操作(pow
返回double
)而不是简单地左移4*len
。更好的方法是在每次迭代时简单地将decimal
左移4位,并将半字节添加(或OR)到最低有效位。通过这种方式,第一个半字节最终将最终到达应有的位置。
此外,字符文字可以作为数字使用,因此如果分别减去48, 97, 65
,它将不会减去'0', 'f', 'F'
,而是会更好。