如何解决C中的十六进制到整数转换
我正在尝试构建自己的函数,将十六进制数转换为十进制整数。
#include <stdio.h>
#include <string.h>
#define SIZE 30
/* this code will conver string hexo number to integer */
int myhtoi(char[]);
int main(int argc,char const *argv[])
{
char heX[SIZE];
scanf("%s",heX);
printf("%d",myhtoi(heX));
return 0;
}
int myhtoi(char input[])
{
int i = 0;
int num = 0;
int result = 0;
for(i = strlen(input); i >= 0;i --)
{
if((input[i] >= 'a' && input[i] <= 'f') || (input[i] >= 'A' && input[i] <= 'F'))
{
switch (input[i])
{
case 'a':
num = 10;
break;
case 'b':
num = 11;
break;
case 'c':
num = 12;
break;
case 'd':
num = 13;
break;
case 'e':
num = 14;
break;
case 'f':
num = 15;
break;
case 'A':
num = 10;
break;
case 'B':
num = 11;
break;
case 'C':
num = 12;
break;
case 'D':
num = 13;
break;
case 'E':
num = 14;
break;
case 'F':
num = 15;
break;
default:
break;
}
}
num = input[i];
printf("%d\n",num);
printf("%c\n",input[i]);
result = result + num;
}
return result;
}
我的逻辑是,当插入输入时,它从字符数组的末尾读取它并一直扫描到前面。
但是,它给了我不正确的输出。 我想我可能对 C 中 char 和 integer 的工作方式没有完全理解。
有人可以告诉我这段代码中我的问题在哪里吗?
解决方法
你应该有
else
num = input[i] - '0';
代替
num = input[i] - '0';
你也可以把它作为你的默认开关(不需要检查它是否在'a'和'z'以及'A'和'Z'之间):
switch (tolower(input[i]))
{
case 'a':
num = 10;
break;
case 'b':
num = 11;
break;
case 'c':
num = 12;
break;
case 'd':
num = 13;
break;
case 'e':
num = 14;
break;
case 'f':
num = 15;
break;
default:
num = input[i] - '0';
break;
}
更重要的是,您还必须将数字从字符转换为整数,'0' 是字符,0 是对应的值。
参考 ASCII 表,'0'
位于位置 48
或 0x30
,因此减去 '0',48 or 0x30
将为您提供正确的对应值。
注意:这里假设您获得了有效的输入(只有从 a 到 f 的字母、大写或小写以及数字)。
,一些事情:
for(i = strlen(input); i >= 0;i --)
strlen()
返回终止 NUL 之前的字符数,因此在 i = strlen(input)
之后,input[i]
就是那个 NUL。可能不是您要处理的字符。您正在那里执行 printf("%c\n",input[i]);
,但 NUL 字节通常不会明显打印,因此可能很难错过。
if((input[i] >= 'a' && input[i] <= 'f') || (input[i] >= 'A' && input[i] <= 'F'))
如果不是有效的十六进制字母怎么办?实际上,如果它不是有效的十六进制字母 并且 也不是数字怎么办?您需要以某种方式处理无效输入。
num = input[i];
这看起来是无条件的,并且会覆盖该开关设置的任何内容。此外,它取的是input[i]
的字符代码,而不是对应数字的数值。就像 'A'
是 0x41
,'1'
是 0x31
等等。您还需要将数字 0-9
转换为数字,与您对 {{1} 所做的相同}.
a-f
这不就是不考虑位置而对数字求和吗?也就是说,result = result + num;
会给出 3,而不是 256+16+1。每向左移动一个字符,该数字的值就会乘以 16。
我建议你:
- 将获取单个数字的数值拆分为一个单独的函数,例如
111
,您可以按照您喜欢的任何方式实现该函数。然后测试它是否返回正确的值,即int hexdigit(char c)
为 1,1
和a
为 10 等。 - 从左到右而不是从右到左进行数字解析。这样,每次获得下一个有效数字时,您只需将这个值乘以 16。也就是说,
A
会读作 1,然后 161+2 = 18,然后 1618+3 = 291。 你也可以在另一个方向上做,但你需要在某处有“当前”数字的 base-16 因子。 - 检查并重新检查索引,以免处理 NUL 或字符串之外的任何内容。
- 然后,对无效输入做一些处理。要么让
123
给出无效字符的错误值,要么让另一个函数检查它。无论哪种情况,请在主循环中检查,并做一些明智的事情。例如。如果输入是hexdigit()
,您可能不希望12x4
和x
都影响返回值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。