C:使用scanf()函数代替gets

时间:2017-03-24 15:12:51

标签: c string shell

/* 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);。非常感谢你。

3 个答案:

答案 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位)生成valval * pow(16, len);(in)有效地将半字节移动到正确的位置。但是,此代码使用浮点数学来完成此操作(pow返回double)而不是简单地左移4*len。更好的方法是在每次迭代时简单地将decimal左移4位,并将半字节添加(或OR)到最低有效位。通过这种方式,第一个半字节最终将最终到达应有的位置。

此外,字符文字可以作为数字使用,因此如果分别减去48, 97, 65,它将不会减去'0', 'f', 'F',而是会更好。