C语⾔⼗进制整数字符串转⼗六进制字符串
【问题描述】
例如:输⼊字符串str1[]=“87632394”,需转成字符串str2[]=“5392A0A”
【解决⽅案】
⽅案1:
先使⽤strtol函数将字符串转成⼗进制数,再通过sprintf函数将⼗进制数按⼗六进制字符串形式输出到字符数组保存该⽅案弊端:转换的数不能⼤于0x7FFFFFFF,因为strtol的返回值是long型
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
char str1[]="87632394";
char str2[100]={0};
char* endptr;
long data =0;
data =strtol(str1,&endptr,10);
printf("data=%ld\r\n",data);
sprintf(str2,"%X",data);
printf("str2=%s\r\n",str2);
return0;
}
运⾏结果:
⽅案2:
解决当要转换的值⼤于0x7FFFFFFF,如何处理
例如:输⼊str1[]="86281102005404”,需转成str2[]=“4E78E26F949C”
⾸先要解决的是如何把"86281102005404”转成数字保存
借atol函数的理念来⾃⼰实现⼀个
__int64 my_atoll(char* str)//__int64可以改成long long,VC++6.0不⽀持long long,C99中才添加long long {
__int64 s =0;
BOOL isMinus = FALSE;//负
while(*str ==' ')//跳过空格
{
str++;
}
if(*str =='+'||*str =='-')
{
if(*str =='-')
isMinus = TRUE;
str++;
}
else if(*str <'0'||*str >'9')//如果第1位既不是符号也不是数字,直接返回异常值
return0;
while(*str !='\0'&&*str >='0'&&*str <='9')
{
s = s *10+*str -'0';
str++;
}
return s *(isMinus ?-1:1);
}
//测试
int main(void)
{
char str[]="86281102005404";
printf("str=%lld\r\n",my_atoll(str));
return0;
}
已验证:(以上代码在VS2019上运⾏测试,在VC++6.0上不⽀持%lld打印)
然后要把数字转成⼗六进制字符,依然可以使⽤sprintf
__int64 my_atoll(char* str)
{
__int64 s =0;
BOOL isMinus = FALSE;//负
while(*str ==' ')//跳过空格
{
str++;
}
if(*str =='+'||*str =='-')
{
if(*str =='-')
isMinus = TRUE;
str++;
}
else if(*str <'0'||*str >'9')//如果第1位既不是符号也不是数字,直接返回异常值
return0;
while(*str !='\0'&&*str >='0'&&*str <='9')
{
s = s *10+*str -'0';
str++;
}
return s *(isMinus ?-1:1);
}
int main(void)
{
char str[]="86277343909020";
char strhex[100]={0};
long long data=0;
data =my_atoll(str);
printf("str=%lld\r\n",data);
数组转换成字符串if(data>0xFFFFFFFF)
{
sprintf(strhex,"%X%08X",(unsigned int)(data>>32),(unsigned int)data);
}
else
{
sprintf(strhex,"%X",(unsigned int)data);
}
printf("strhex=%s\r\n",strhex);
return0;
}
运⾏结果:
注意,当数据⼤于0xFFFFFFFF,sprintf中%08X是必要的,不要写成%X,因为0需要打出来。
⽅案三:
接上⾯的⽅案⼆,my_atoll还是要⽤,只是将数字转成⼗六进制字符串可以⾃⼰实现。
void ltoh(long long x,char* p)
{
int div;
int cnt =0;
if(x ==0){
*p ='0';
}
if(x <0){
x =-x;
*p ='-';
p++;
}
for(int i =0; x !=0; i++){
div = x %16;
x = x /16;
if((div -10)<0)
*(p + i)= div +'0';
else*(p + i)='A'+ div -10;
div =0;
cnt++;
}
//reverse颠倒
for(int i =0; i < cnt /2; i++){
char temp = p[i];
p[i]= p[cnt -1- i];
p[cnt -1- i]= temp;
}
}
int main(void)
{
char str[]="86281102005404";
char strhex[100]={0};
long long data =0;
data =my_atoll(str);
printf("str=%lld\r\n", data);
ltoh(data,strhex);
printf("strhex=%s\r\n", strhex);
return0;
}
my_atoll函数见⽅案⼆。
运⾏结果:
如果⽐0xFFFF FFFF FFFF FFFF更⼤的数要转成⼗六进制字符串,就不在这⾥讨论了
PS.
vc++6.0由于版本过于陈旧,不⽀持long long,可以改⽤__int64来定义
报错:error C2632: ‘long’ followed by ‘long’ is illegal
微软最终在Visual Studio 2013上增加了对long long和unsigned long long的⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论