1.atoi函数简介
(1).atoi函数原型 :int atoi (const char * str);
(2).头文件:<stdlib.h>
用法:将字符串里的数字字符转化为整形数。返回整形值。
注意:
转化时跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将转换结果返回。
如果遇到的第一个非空字符不是数字或正负号,则直接返回0
如果要转换后的值超过了int的最大值(或最小值),那么atoi就返回int的最大值(或最小值)
函数代码
int my_atoi(const char* str)
{
assert(str!=NULL);//断言,判断str是否为空指针
long long ret = 0;
int flag = 1;
while (isspace(*str))//判断是不是空格字符
str++;
if (*str != '+' && *str != '-' && !isdigit(*str))//判断第一个非空字符
{
return 0;
}
else//第一个非空字符是正负号,指针向后走
{
if (*str == '+' )
{
str++;
flag = 1;//符号位
}
else if (*str == '-')
{
str++;
flag = -1;//符号位
}
}
while (*str != '\0')
{
if (isdigit(*str))//是数字字符
{
ret = ret * 10 + flag * (*str - '0');//先取出的数字放到高位,即 *10
str++;
if (ret > INT_MAX)
{
ret = INT_MAX;
}
if (ret < INT_MIN)
{
ret = INT_MIN;
}
}
else//不是数字字符
{
return (int)ret;//返回结果
}
}
return (int)ret;
}
2.优化
对于我们所写的这个函数,还可以进行优化
atoi的转化有两种情况
(1).走到了字符串的末尾
(2).没有走到字符串末尾
可以定义一个枚举类型来判断这两种情况
enum Sit
{
Leg,//合法的
IILeg//非法的
}sit = IILeg;
优化后的代码
enum Sit
{
Leg,//合法的
IILeg//非法的
}sit = IILeg;
int my_atoi(const char* str)
{
assert(str!=NULL);//断言,判断str是否为空指针
long long ret = 0;
int flag = 1;
while (isspace(*str))//判断是不是空格字符
str++;
if (*str != '+' && *str != '-' && !isdigit(*str))//判断第一个非空字符
{
return 0;
}
else//第一个非空字符是正负号,指针向后走
{
if (*str == '+' )
{
str++;
flag = 1;//符号位
}
else if (*str == '-')
{
str++;
flag = -1;//符号位
}
}
while (*str != '\0')
{
if (isdigit(*str))//是数字字符
{
ret = ret * 10 + flag * (*str - '0');//先取出的数字放到高位,即 *10
str++;
if (ret > INT_MAX)
{
ret = INT_MAX;
}
if (ret < INT_MIN)
{
ret = INT_MIN;
}
}
else//不是数字字符
{
return (int)ret;//返回结果
}
}
if (*str == '\0')//合法转换
{
sit = Leg;
}
return (int)ret;
}
3.测试
测试函数代码
我们先来测试一下模拟实现是否成功(省略了函数代码)
以下罗列了几种情况:
int main()
{
char str1[] = "0894";
char str2[] = " w894";
char str3[] = " +894";
char str4[] = " -894";
int ret1 = atoi(str1);
int ret1_ = my_atoi(str1);
int ret2 = atoi(str2);
int ret2_ = my_atoi(str2);
int ret3 = atoi(str3);
int ret3_ = my_atoi(str3);
int ret4 = my_atoi(str4);
int ret4_ = my_atoi(str4);
printf("atio库函数实现 = %d\n", ret1);
printf("模拟实现 = %d\n", ret1_);
printf("atio库函数实现 = %d\n", ret2);
printf("模拟实现 = %d\n", ret2_);
printf("atio库函数实现 = %d\n", ret3);
printf("模拟实现 = %d\n", ret3_);
printf("atio库函数实现 = %d\n", ret4);
printf("模拟实现 = %d\n", ret4_);
return 0;
}
效果
测试优化后的代码
int main()
{
char arr[] = " -456a895";
int ret = my_atoi(arr);
if (sit == Leg)
{
printf("合法转换:%d\n", ret);
}
else
{
printf("非法转换:%d\n", ret);
}
return 0;
}
效果: