C 为什么我的十六进制转换函数关闭了一个?
我试图学习c语言,但我不明白为什么我的十六进制到整数转换函数会返回一个关闭的值 注:0XAAAA==46390C 为什么我的十六进制转换函数关闭了一个?,c,C,我试图学习c语言,但我不明白为什么我的十六进制到整数转换函数会返回一个关闭的值 注: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"
#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;
}
更新:我现在意识到“-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;
如果(input[i]>='0'&&input[i]='a'&&input[i]='a'&&input[i]您有几个错误,例如字符串没有以null结尾,ASCII到十进制的转换是无意义的(值55?),您不需要初始化sum
等等。只需执行以下操作:
#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;
}
#包括
#包括
int main()
{
字符x[]=“AAAA”;
无符号整数和=strtoul(x,NULL,16);
printf(“%d 0X%X\n”,和,和);
返回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;
}
#包括
#包括
#包括
无符号整数十六进制到整数(const char*str);
int main()
{
字符x[]=“AAAA”;
无符号整数和=hexstr到uint(x);
printf(“%d 0X%X\n”,和,和);
返回0;
}
无符号整数十六进制到整数(常量字符*str)
{
无符号整数和=0;
对于(;*str!='\0';str++)
{
总和*=16;
if(isdigit(*str))
{
sum+=*str-'0';
}
其他的
{
字符位数=toupper(*str);
_静态_断言('Z'-'A'==25,“不支持垃圾系统”);
如果(digit>='A'&&digit您有几个错误,例如字符串没有以null结尾,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;
}
#包括
#包括
int main()
{
字符x[]=“AAAA”;
无符号整数和=strtoul(x,NULL,16);
printf(“%d 0X%X\n”,和,和);
返回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;
}
#包括
#包括
#包括
无符号整数十六进制到整数(const char*str);
int main()
{
字符x[]=“AAAA”;
无符号整数和=hexstr到uint(x);
printf(“%d 0X%X\n”,和,和);
返回0;
}
无符号整数十六进制到整数(常量字符*str)
{
无符号整数和=0;
对于(;*str!='\0';str++)
{
总和*=16;
if(isdigit(*str))
{
sum+=*str-'0';
}
其他的
{
字符位数=toupper(*str);
_静态_断言('Z'-'A'==25,“不支持垃圾系统”);
如果(digit>='A'&&digit您只是在编逻辑,那么没有一个值可以从十六进制数字字符中减去以将其转换为相应的数字
如果你想便于携带,C所需要的只是符号0
到9
在编码中是连续的。字母A
到F
没有这样的保证
在这项低级整数工作中,还涉及到双精度浮点函数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的代码低,hih:).您只是在编逻辑,没有一个值可以从十六进制数字字符中减去,将其转换为相应的数字
如果你想便于携带,C所需要的只是符号0
到9
在编码中是连续的。字母A
到F
没有这样的保证
在这项低级整数工作中,还涉及到双精度浮点函数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的代码低,hih:).为什么要减去55,它不应该是'0'
?而且,x
不够大,无法存储“AAAA”
您忘了说明'\0'
55可以是-A'+10,但这意味着代码对数字0不起作用-9@CinCout-'0'
也不起作用-用于十六进制的字符在ASCII字符集中是不连续的。除非您是在代码高尔夫或模糊C挑战领域工作,否则请给出变量(和函数)专有名称。为什么要减去55,它不应该是'0'
?而且,x
不够大,无法存储'AAAA“
您忘了说明'\0'
55可以是-A'+10,但这意味着代码对数字0不起作用-9@CinCout-'0'
也不起作用-用于十六进制的字符在ASCII字符集中是不连续的。除非您是在代码高尔夫或模糊C挑战领域工作,否则请给出变量(及职能)专有名称。仍然无法回答如何更正逻辑以达到要求。就是这样,谢谢!不确定我从哪里得到55个字符,只是从臀部射击。它适用于单字符十六进制值。@JoshuaBradley,它适用于9以上的大写数字。这是22个可能字符中的6个。也许你应该提及OP代码中的UB,并将其作为一个完整的答案。我将删除我的。另外,感谢您提供的字符指针示例,我一直在想这个问题。正如@CinCout所指出的,它比硬编码的限制要好。仍然无法回答如何更正逻辑以达到要求。就是这样,谢谢!不确定我从哪里得到了55从,只是从臀部射击真的,很有效