【问题标题】:Hex to int conversion in CC中的十六进制到整数转换
【发布时间】:2021-02-24 21:03:50
【问题描述】:

我正在尝试构建自己的函数,将十六进制数转换为十进制整数。

#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;

}

我的逻辑是,当输入被插入时,它从 char 数组的末尾读取它并一直扫描到前面。

但是,它给了我不正确的输出。 我想我可能对 char 和 integer 在 C 中的工作方式没有完全理解。

有人能告诉我这段代码的问题在哪里吗?

【问题讨论】:

  • 你错过了 else 条件
  • strtol (ptr, &amp;endptr, 0) 是另一种处理八进制和十六进制转换的快速方法。 (在你锻炼之后——这是一个很好的锻炼)
  • 注意字符'1'不是整数1
  • 你可以用num=tolower(input[i]) - 'a' + 10替换你的switch声明

标签: c hex


【解决方案1】:

你应该有

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' 位于位置480x30,因此减去'0', 48 or 0x30 将得到正确的对应值。

注意:这假设您有一个有效的输入(只有从 a 到 f 的字母、大写或小写字母以及数字)。

【讨论】:

  • 我按照您建议的方式完成了我设法将字母转换为整数的方式。但是,我仍然没有得到整数到整数。 a -> 10 b->11 但 1 ->0
【解决方案2】:

一些事情:

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 转换为数字,就像您对a-f 所做的一样。

result = result + num;

这不只是将数字相加而不考虑它们的位置吗?也就是说,111 将给出 3,而不是 256+16+1。每向左移动一个字符,该数字的值就会乘以 16。


我建议你:

  • 将单个数字的数值拆分为单独的函数,例如int hexdigit(char c),您可以以任何您喜欢的方式实现它。然后测试它是否返回正确的值,即1 为 1,aA 为 10 等。
  • 从左到右而不是从右到左解析数字。这样,每次获得下一个有效数字时,您可以将这个值乘以 16。也就是说,123 将被读取为 1,然后 161+2 = 18,然后 1618+3 = 291。 您也可以在另一个方向上执行此操作,但您需要在某处拥有“当前”数字的 base-16 因子。
  • 检查并重新检查索引,以免处理 NUL 或字符串之外的任何内容。
  • 然后,对无效输入进行处理。要么让hexdigit() 为无效字符提供错误值,要么让另一个函数检查它。在任何一种情况下,在主循环中检查它,并做一些明智的事情。例如。如果输入是12x4,您可能不希望x4 都影响返回值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-12
    • 2010-10-16
    • 2011-02-04
    • 1970-01-01
    • 2011-08-11
    • 2015-04-23
    相关资源
    最近更新 更多