atoi函数原型为:int atoi( constchar *string );
其功能是将一个数字字符串转换成int类型的整数,若数字前有空格,可以跳过空格。
模拟实现此函数,初看之下,觉得此题简单,写了如下代码:
int change(const char *p)
{
int num = 0;
while (*p)
{
num = num * 10 + *p - '0';
p++;
}
return num;
}
int main()
{
char *p = "123";
int ret = change(p);
printf("%d\n", ret);
return 0;
}
但仔细想想,这样写没有考虑全面,没有考虑到传参时若传了空指针,没有考虑到负数,空字符串,字符串前有空格,字符串中有其他非数字字符。
综合考虑,模拟实现如下:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
enum STATE
{
VALID,//合法
INVALID//非法
};
enum STATE state = INVALID;
int my_atoi(const char *str)
{
int flag = 1;
long long ret = 0;
//空指针
assert(str != NULL);
//处理空字符串
if (*str == '\0')
return 0;//返回结果为非法
//处理空格
while (isspace(*str))
{
str++;
if (*str == '\0')
return 0;//字符串只有空格
}
//+-号
if (*str == '+')
str++;
if (*str == '-')
{
flag = -flag;
str++;
}
//字符串处理
while (*str)
{
if (isdigit(*str))
{
ret = ret*10 + (*str-'0')*flag;
//溢出
if ((ret > INT_MAX) || (ret < INT_MIN))
{
state = VALID;
return (int)ret;
}
}
else//非数字字符
{
return (int)ret;//返回结果为非法
}
str++;
}
state = VALID;
return (int)ret;
}
int main()
{
char *p = " -123";
int ret = my_atoi(p);
if (state == VALID)//合法时,输出结果
printf("%d\n", ret);
}
定义全局变量stste,并设置初值为INVALID,在函数实现中当遇到合法的返回时时,将其改为VALID,在测试时加入if判断,这样可以将合法的返回值与非法的返回值区分开。定义ret为long long类型,不能为int 类型,否则,在计算时会发生截断,这样ret永远不会到达int 类型的最大值或最小值。
运行结果: