为什么我的十六进制转换函数关闭一个?

时间:2017-12-15 08:56:26

标签: c

我正在尝试学习c并且很困惑为什么我的hex到int转换函数会返回一个值为1的值。

注意:0XAAAA == 46390

#include <stdio.h>
#include <math.h>

unsigned int hex_to_int(char hex[4]);

int main()
{
    char hex[4] = "AAAA";

    unsigned int result = hex_to_int(hex);
    printf("%d 0X%X\n", result, result);
    return 0;
}    

unsigned int hex_to_int(char input[4])
{
    unsigned int sum, i, exponent;

    for(i = 0, exponent = 3; i < 4; i++, exponent--) {
        unsigned int n = (int)input[i] - 55;
        n *= pow(16, exponent);
        sum += n;
    }   
    return sum;
}

输出:

46391 0XAAAB

更新:我现在意识到“ - 55”太荒谬了,我看到了这个记忆:

if (input[i] >= '0' && input[i] <= '9')
    val = input[i] - 48;
else if (input[i] >= 'a' && input[i] <= 'f')
    val = input[i] - 87;
else if (input[i] >= 'A' && input[i] <= 'F')
    val = input[i] - 55;

2 个答案:

答案 0 :(得分:4)

你有几个错误,例如字符串没有被终止,并且ASCII到十进制的转换是无意义的(值55?),你没有初始化#include <stdio.h> #include <stdlib.h> int main() { char x[] = "AAAA"; unsigned int sum = strtoul(x, NULL, 16); printf("%d 0X%X\n", sum, sum); return 0; } ,依此类推。只需这样做:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

unsigned int hexstr_to_uint(const char* str);

int main()
{
  char x[] = "AAAA";

  unsigned int sum = hexstr_to_uint (x);
  printf("%d 0X%X\n", sum, sum);
  return 0;
}    

unsigned int hexstr_to_uint(const char* str)
{
  unsigned int sum = 0;

  for(; *str != '\0'; str++)
  {
    sum *= 16;
    if(isdigit(*str))
    {
      sum += *str - '0';
    }
    else
    {
      char digit = toupper(*str);
      _Static_assert('Z'-'A'==25, "Trash systems not supported.");
      if(digit >= 'A' && digit <= 'F')
      {
        sum += digit - 'A' + 0xA;
      }
    }
  }
  return sum;
}

修改

如果您坚持要手动执行此操作:

{{1}}

答案 1 :(得分:0)

您只是编写逻辑,没有单个值可以从十六进制数字字符中减去以将其转换为相应的数字。

如果您想要可移植,那么C所要求的是符号09在编码中是连续的。字母AF没有这样的保证。

在这个低级整数工作中还涉及pow()这是一个双精度浮点函数,有点不和谐。执行此操作的典型方法是乘法或按位移位。

如果你自己一心想做转换,我通常会这样做:

unsigned int hex2int(const char *a)
{
  unsigned int v = 0;
  while(isxdigit((unsigned int) *a))
  {
    v *= 16;
    if(isdigit((unsigned int) *a))
      v += *a - '0';
    else
    {
      const char highs[] = "abcdef";
      const char * const h = strchr(highs, tolower(*a));
      v += 10 + (unsigned int) (h - highs);
    }
    ++a;
  }
  return v;
}

上面有点冗长,你可以将十进制数字折叠成字母用的字符串,我只是试着说清楚。以上内容适用于任何有效的C字符集编码,而不仅仅是ASCII(并且它比@Lundin的代码更不具有被动攻击性,嗨:)。