atoi函数使用方法
在c++官网中是这样介绍atoi函数的
通俗的讲就是把字符串中的字符数字转换为整形数字,遇到空格就跳过,如果在字符串开始遇到不是有效的整数比如说abc就直接返回0,如果遇到像这种情况123abc345这个就只返回123,这个函数包含在stdlib.h头文件里我们来试一下
# define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
# include<stdlib.h>
int main()
{
char arr[] = { " 123abc345" };
char arr1[] = { " abcd123" };
char arr2[] = { " -123sdf" };
char arr3[] = { " @aq1234" };
int ret = atoi(arr);
int ret2 = atoi(arr1);
int ret3 = atoi(arr2);
int ret4 = atoi(arr3);
printf("%d\n%d\n%d\n%d\n", ret,ret2,ret3,ret4);
return 0;
}
模拟实现atoi
在模拟实现之前我们要考虑清楚有几种情况,第一种就是传的字符串是空指针,第二种是开头有空格需要跳过,第三种就是开头是除开0到9的字符,第四种就是开头是数字字符是正数还是负数,还有就是合法转换和非法转换。下面是代码
# define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
# include<ctype.h>
# include<stdlib.h>
# include<assert.h>
enum State
{
VAILD,//不非法的
INVAILD//非法的
} state = INVAILD;
int my_atoi(const char* str)
{
assert(str != NULL);
if (*str == '\0')
{
return 0;
}
while (isspace(*str))
{
str++;
}
int flag = 1;
if(*str == '-')
{
flag = -1;
str++;
}
if (*str == '+')
{
flag = 1;
str++;
}
long long ret = 0;
while (*str != '\0')
{
if (isdigit(*str))
{
ret = ret * 10 + (*str - '0')*flag;
if (ret > INT_MAX)
{
return INT_MAX;
}
if (ret < INT_MIN)
{
return INT_MIN;
}
}
else
{
return (int)ret;
}
str++;
}
if (*str == '\0')
{
state = VAILD;
}
return (int)ret;
}
int main()
{
char str[] = { " -123abc34" };
int ret = my_atoi(str);
if (state == VAILD)
{
printf("合法转化:%d\n", ret);
}
else
{
printf("不合法转化:%d\n", ret);
}
return 0;
}
分布讲解
nt my_atoi(const char* str)
{
assert(str != NULL);
if (*str == '\0')
{
return 0;
}
while (isspace(*str))
{
str++;
}
int flag = 1;
if(*str == '-')
{
flag = -1;
str++;
}
if (*str == '+')
{
flag = 1;
str++;
}
这一段代码就是解决如果 字符串中的第一个非空格字符序列不是有效的整数,或者由于空或仅包含空格字符而不存在此类序列,则不执行转换并返回零。还有遇到空格字符跳过的情况,这样用了一个函数isspace这个函数就是用来判断是不是空格字符,并且断言了一下传过来的字符串是不是空指针,
如果都不是就进入下面的if语句这里主要就是判断是正数还是负数,其实正数是不需要判断前面是不是有加号的,这样做就主要是为了防止有这样的字符串传过来像+123这种情况,这里设置了一个flag变量来判断是正数还是负数。
long long ret = 0;
while (*str != '\0')
{
if (isdigit(*str))
{
ret = ret * 10 + (*str - '0')*flag;
if (ret > INT_MAX)
{
return INT_MAX;
}
if (ret < INT_MIN)
{
return INT_MIN;
}
}
else
{
return (int)ret;
}
str++;
}
这段代码就除开那上面那些情况来进入下一步判断,首先我们设置了一个长整形来防止整形溢出,然后进入while循环当str字符串解引用不是字符串结尾\0的时候进行,下面进入if语句如果对字符串解引用是一个数字,这里用了一个isdigit函数来判断是否为数字。
ret = ret * 10 + (*str - '0')*flag;
这是一个数学公式用来把字符123变成数字123的,假如字符1想变成数字1就那字符一减去字符0,他们之间的ascii码差值就是数字1,在下面两个if就是一种比较特殊的情况了,在atoi函数定义中如果返回的数字大于intmax和小于intmin就直接返回intmax和intmin,最后那个else就是遇到除开0到9字符遇到其他字符就直接返回了,最后str指针自增1,我们来看看开头设置的一个枚举
enum State
{
VAILD,//不非法的
INVAILD//非法的
} state = INVAILD;
这里就是用来判断返回的到底是合法还是非法的,合法的就是想把字符串中所有的数字都转换完了的就相当于把字符串都遍历了一遍,字符串指针走到了字符结尾非法的就是没有遍历完,没有走到字符串结尾。这里我们首先把他赋值为非法的
if (*str == '\0')
{
state = VAILD;//这里就是判断字符串指针走没走完
}
if (state == VAILD)
{
printf("合法转化:%d\n", ret);
}
else
{
printf("不合法转化:%d\n", ret);
}
根据返回值来判断打印。