atoi的实现
一、使用方式
int atoi( const char *string );
atoi实现的是字符串转整形的操作:
int main()
{
char arr1[20] = "123456";
char arr2[20] = "-123456";
char arr3[20] = "12abc3456";//遇到非数字停止转换
int ret1 = atoi(arr1);
int ret2 = atoi(arr2);
int ret3 = atoi(arr3);
printf("%d %d %d", ret1, ret2, ret3);
return 0;
}
下面我们就来模拟实现:
二、模拟实现
2.1 常规转换
假设要把字符串"123456"转换成整形:
int ret = 0;
while (*str)
{
ret = ret * 10 + *str - '0';
str++;
}
2.2 要处理的特殊情况
1️⃣ 空指针
2️⃣ 空字符串
3️⃣ 空格
4️⃣ 正负号
5️⃣ 越界
6️⃣ 非数字字符
空字符串:
当我们传递的是空字符串时,我们应该返回什么?
如果返回0,那传递的是字符0时该怎么办?
所以要判断是否合法。
我们可一创建一个枚举变量来判断
enum status
{
VALID,// 0
INVALID// 1
}sta = INVALID;
sta是全局变量,先假设不合法,如果合法,后边再改。
if (*str == '\0')
{
return 0;//非法0
}
空格:
遇到空格如果在字符串开头会自动跳过,如果在字符串中间就是第6️⃣种情况,直接跳过。
if (isspace(*str))//判断是不是字符'0'
{
str++;
}
正负号:
int flag = 1;
if (*str == '+')
{
str++;
}
else if(*str == '-')
{
flag = -1;
str++;
}
非数字字符:
while (*str)
{
if (isdigit(*str))//判断是否为数字字符
{
ret = ret * 10 + *str - '0';
}
else
{
return ret;
}
str++;
}
越界判断:
判断是否越界就是看ret是否大于INT_MAX
,对于负数就是小于INT_MIN
,要注意int
是永远不会超过INT_MAX
,应该用long long
if (isdigit(*str))//判断是否为数字字符
{
ret = ret * 10 + flag * (*str - '0');
if (ret > INT_MAX || ret < INT_MIN)
{
return 0;
}
}
else
{
return (int)ret;
}
全代码:
enum status
{
VALID,// 0
INVALID// 1
}sta = INVALID;
int my_atoi(const char* str)
{
int flag = 1;
assert(str);
if (*str == '\0')
{
return 0;//非法0
}
if (isspace(*str))//判断是不是字符'0'
{
str++;
}
if (*str == '+')
{
str++;
}
else if(*str == '-')
{
flag = -1;
str++;
}
long long ret = 0;
while (*str)
{
if (isdigit(*str))//判断是否为数字字符
{
ret = ret * 10 + flag * (*str - '0');
if (ret > INT_MAX || ret < INT_MIN)
{
return 0;
}
}
else
{
return (int)ret;
}
str++;
}
if (*str == '0')
{
sta = VALID;
}
return (int)ret;
}
int main()
{
char arr[200] = "123abc45";
int ret = my_atoi(arr);
if (sta == INVALID)
{
printf("非法返回: %d", ret);
}
else if (sta == VALID)
{
printf("%d", ret);
}
return 0;
}