当它超过两位数时失败....
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);
答案 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位宽,short
且int
必须至少为16位宽,long
必须至少为32位比特宽,sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)
(对于那些类型的无符号版本也是如此)。
int
可能是16到64位宽,具体取决于平台。
此外,您的代码还有另一个问题,可能导致将来执行错误。
您的数组下标i
是char
,编译器应该已经为您提供了
警告:数组下标的类型为&#39; char&#39;。
它之所以这样,是因为类型char
可以是签名的或无符号的 - 它取决于编译器。如果char
已签名,则i
可能为否定,在这种情况下,访问负数组索引会导致未定义的行为。
我强烈建议您查看此answer以避免将来出现常见问题。
提示:始终正确格式化您的代码,它可以帮助您进行可视化,也可以帮助您尝试在其中找到问题。
Downvoter Care To Explain为什么他被投票。
答案 2 :(得分:0)
首先,转换时必须考虑如何表示十六进制。它是小端,因此你必须从字符串的最右边部分开始。
接下来,您必须考虑在每一步中,十六进制转换将需要基数16(因为这是十六进制的转换)到位置的幂。
之后你必须确定如何从另一个中减去ASCII表示(只是二进制),例如:
然后,我们可以应用此算法在每种情况下获得十六进制转换。代码看起来像这样:
#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;
}