字符串转int函数:
函数名:Myatoi(*str)
功能:将一串字符串转成int整形数字
注意事项:
1.int型最大取值范围:2147483647,int型占4字节,即4*8 = 32位二进制,整数在二进制中用原码表示即可,第一位为符号位0表示正数,即:01111111 11111111 11111111 11111111,十六进制(HEX)表示为:0fff ffff,十进制计算方法为:2^31 – 1;最小值:十六进制为:0x80000 0000(HEX),二进制为:10000000 00000000 00000000 00000000(BIN),十进制计算方法为:-1*2^31。
2.编程时,我第二次用了分开计算正数和负数的方法。由于第一次计算正数,得出负数时是把sum × (-1),这样计算就会有bug。因为正数的最大值为2147483647,所以×(-1)得到的负数最小值为-2147486947,而不是0x8000 0000(HEX)。
3.注意int类型和char类型一样是,表示的范围是循环的,我们知道char类型范围是:-128 — 127 ,如果char a = 127,b = a+1;那么b就为-128;
所以int同理,我们可以用sum>0或者sum<0判断sum是否超出的正数或者负数的表示表示范围。例如:我们求sum为整正数,sum = sum*10 +*str – ‘0’,此时sum为2147483647,sum再加一个1 ,就超出了int表示的正数范围,2147483647 + 1 为 -2147483648 ,这是一个负数了,此时sum<0,所以sum = MAXINT(最大int正数)。
同理sum表示负数时,若sum一直减,减到最小后再减就>0了,此时就可以退出循环,sum = MININT就ok了。
4.先写了10进制的情况;十六进制和八进制的情况,不需要像10进制一样考虑 负号和正号。
5.用到的几个字符函数:
isdigit();//判断字符是否为数字
isxdigit();//判断参数字符是否为16进制字符,即A-F,a-f
toupper();//如果参数字符是小写字母,则转化成大写字母
6.将字符转化为int整数时候:
如果是数字字符,’a’ – ‘0’ 减字符0即可。
如果是字母,‘B’ – ‘A’ +10;//表示11。16进制的计算时要用到
7.还有一个问题:十六进制和八进制的sum判断是否超出范围,在定义sum时将其定义为long long类型,进行加法加法运算时候,if(sum >maxint),就退出循环,返回maxInt。再将最后的结果转化为int类型。
程序用例:
#include<ctype.h>
#include<assert.h>
#include<stdio.h>
#define MAXINT 0x7fffffff //int范围内的最大正数
#define MININT 0x80000000 //最小的负数
int Str_To_Int_DEC(char *str)//10进制
{
int sum = 0;
int flag = 1;//判断正负数 1表示正数 -1 表示负数
bool first_sum = true;//做负数运算时 判断第一次运算是否执行
while(*str == ' ')
{
str++;
}
if(*str == '-')
{
flag = -1;
str++;
}
else if(*str == '+')
{
str++;
}
while(isdigit(*str))
{
if(flag == 1)
{
sum = sum*10 + *str -'0';
str++;
if(sum < 0)
{
return MAXINT;
}
}
else if(flag == -1)
{
if(first_sum == true)
{
sum = -(*str-'0');//第一个数为负数
str++;
first_sum = false;
}
else if(first_sum == false)
{
sum = sum*10 - (*str - '0');
str++;
}
if(sum > 0)
{
return MININT;
}
}
}
return sum;
}
int Str_To_Int_HEX(char *str)//16进制
{
long long sum = 0;
while(*str == ' ')
{
str++;
}
while(isxdigit(*str))//int isxdigit();功能:如果参数是十六进制数字字符(即:A-F, a-f, 0-9),函数返回非零值,否则返回零值。
{
if(isalpha(*str))
{
sum = sum*16 + toupper(*str) -'A'+10;//如果是字母的话
str++;
}
else if(isdigit(*str))
{
sum = sum*16 + *str -'0';
str++;
}
if(sum > MAXINT)
{
sum = MAXINT;
break;
}
}
return (int)sum;
}
int Str_To_Int_OCT(char *str)//8进制
{
long long sum = 0;
while(*str == ' ')
{
str++;
}
while(*str>= '0' && *str <= '7')
{
sum = sum*8 + *str -'0';
str++;
if(sum > MAXINT)
{
sum = MAXINT;
break;
}
}
return (int)sum;
}
int Myatoi(char *str)
{
assert(str != NULL);
int result;
while(isspace(*str))
{
str++;
}
if(*str == '0')
{
str++;
if(*str == 'x' || *str == 'X')
{
str++;
result = Str_To_Int_HEX(str);
}
else
{
result = Str_To_Int_OCT(str);
}
}
else
{
result = Str_To_Int_DEC(str);
}
return result;
}
int main()
{
char *str1 = "321564";
char *str2 = "2147483647";
char *str3 = "2147483648";
char *str4 = "+326549875646156";
char *str5 = "-321564";
char *str6 = "-2147483648";
char *str7 = "-2147483649";
char *str8 = "0x7fffffff";
char *str9 = "80000000";
char *str10 = "0x654ab";
char *str11 = "0Xbbb";
printf("%d\n", Myatoi(str1));
printf("%d\n", Myatoi(str2));
printf("%d\n", Myatoi(str3));
printf("%d\n", Myatoi(str4));
printf("%d\n", Myatoi(str5));
printf("%d\n", Myatoi(str6));
printf("%d\n", Myatoi(str7));
printf("%d\n", Myatoi(str8));
printf("%d\n", Myatoi(str9));
printf("%d\n", Myatoi(str10));
printf("%d\n", Myatoi(str11));
return 0;
}
下面是十进制的测试结果: