C程序将十六进制转换为整数

时间:2017-01-26 06:22:32

标签: c hex

当它超过两位数时失败....

EG。输入:0xf输出:15
但输入:0xFF输出:-1

char s[20],hexdigit=0,i=0,deci=0;
scanf("%[^\n]",s);
if(s[0]=='0' && (s[1]== 'X' || s[1]=='x'))
    i=2;
for(;s[i]!='\0';i++){

    if(s[i]>='0' && s[i]<='9')
        hexdigit=s[i]-'0';
    else if(s[i]>='a' && s[i]<='f')
        hexdigit=s[i]-'a'+10;
    else if(s[i]>='A' && s[i]<='F')
        hexdigit=s[i]-'A'+10;
    else
        break;
    deci=(16*deci)+hexdigit;
}
    printf("\n%d",deci);  

3 个答案:

答案 0 :(得分:5)

系统中的char类型只能存储-128+127之间的值。要获得更大的范围,请使用其他数据类型。

而不是

char deci = 0;

int deci = 0;

这种类型也会溢出,但很久以后。通常位于2147483647.当您尝试解析任何较大的值时,行为未定义

您可以通过编写

进一步了解
unsigned int deci = 0;

此类型将在4294967295处溢出,之后它将再次以0开始。此处没有未定义的行为。

答案 1 :(得分:0)

您使用的char只能存储-128+127之间的值。而是使用其他数据类型来获得更多的alrger范围。

所以而不是

  char deci = 0;

使用int

  int deci  = 0;   

即使它溢出,您也可以使用unsigned int(因为您的代码只读取非负值)

  unsigned int = 0;
  

C标准保证char必须至少为8位宽,shortint必须至少为16位宽,long必须至少为32位比特宽,sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)(对于那些类型的无符号版本也是如此)。

     

int可能是16到64位宽,具体取决于平台。

此外,您的代码还有另一个问题,可能导致将来执行错误。

您的数组下标ichar,编译器应该已经为您提供了

  

警告:数组下标的类型为&#39; char&#39;。

它之所以这样,是因为类型char可以是签名的或无符号的 - 它取决于编译器。如果char已签名,则i可能为否定,在这种情况下,访问负数组索引会导致未定义的行为。 我强烈建议您查看此answer以避免将来出现常见问题。

提示:始终正确格式化您的代码,它可以帮助您进行可视化,也可以帮助您尝试在其中找到问题。

Downvoter Care To Explain为什么他被投票。

答案 2 :(得分:0)

首先,转换时必须考虑如何表示十六进制。它是小端,因此你必须从字符串的最右边部分开始。

接下来,您必须考虑在每一步中,十六进制转换将需要基数16(因为这是十六进制的转换)到位置的幂。

之后你必须确定如何从另一个中减去ASCII表示(只是二进制),例如:

  1. &#39; E&#39; - &#39; A&#39;将产生1110(E) - 1010(A)= 0100(4或十进制值 减法)
  2. 因为范围A-F的十进制偏移而加10:0100(E-A)+ 1010(10)= 14
  3. 乘以16的基本功率到给定位置(所以0)
  4. 然后,我们可以应用此算法在每种情况下获得十六进制转换。代码看起来像这样:

    #include <stdio.h>
    #include <math.h>
    int htoi(char s[]);
    int my_strlen(char s[]);
    
    
    int main(int argc, char **argv) {
        unsigned long int val;
        val = htoi("0x4E"); //Check N
        if (val > 0)
            printf("Value val: %lu", val);
        else
            printf("improperly formatted");
        return 0;
    }
    
    //Coded for example
    int htoi(char s[]) {
        int i, j;
        unsigned long int z;
        i = z = 0;
        j = my_strlen(s) - 1;
    
        if(j < 2) return z;
        if (s[i++] != '0') return z;
        if (s[i] != 'X' && s[i] != 'x') return z;
    
        //Reset i to represent position
        i = 0;
        //Convert hexidecimal to integer
        for(i = 0; s[j] != 'x' && s[j] != 'X'; j--, i++) {
            if(s[j] >= '0' && s[j] <= '9')
                z =  z + (s[j] - '0') * pow(16, i);
            else if(s[j] >= 'a' && s[j] <= 'f')
                z = z + ((s[j] - '0') + 1) * pow(16, i);
            else if(s[j] >= 'A' && s[j] <= 'F')
                z = z + ((s[j] - 'A') + 10) * pow(16,i);
            else
                continue;
        }
        return z;
    }
    
    //Coded for example
    int my_strlen(char s[]) {
        int i = 0;
        while(s[i] != '\0')
            i++;
        return i;
    }