在剑指offer里第49道题的要求是把字符串转换成整数,在这种情况下肯定是不能用像atoi这样的库函数的哦,所以我们就得模拟实现这个函数来解决面试官所给的问题。很多人可能会一下就写出这样的代码:
int my_atoi(const char *str)
{
int number=0;
assert(str);
while(*str)
{
number=number*10+*str-'0';
str++;
}
return number;
}
如果你写出这样的代码那么就太小看面试官了哈!!!这个代码看似能达到要求,但是细想一下里面存在着很多的问题,下来我们对这个题做进一步分析:
1.如果输入的字符串不全是数字字符呢?
例如:“123adc4".
针对这种情况,我们需要进行判断遇到不是数字字符的就直接返回。
2.如果在数字字符前面有正负号又该怎么办?
例如:”-123”、“+123”.
针对这种情况,我们须得判断字符串的第一个字符是正号还是负号,并用一个标记位flag记录正负。
3.当输入的字符串前面几个字符都是空格又该怎么办?
例:“ -123”,“ +123”.
针对这种情况,库里面的atoi是将空格跳过再进行判断的,所以我们在一开始就用循环将空格跳过。
4.当字符串中的字符数字转化的整数太大,会有可能溢出?
针对这种情况,我们需要做出一个判断,判断转化后的数字在long的范围内。
5.
当输入的字符串为空或者是“0”时,我们应该返回什么呢?
我们在这两种情况下都返回0吗?如果都返回0,那么当这个函数的调用者得到返回值0的时候,他怎么知道是 哪种情况?atoi是通过一个全局变量来区分的。如果是非法输入,返回0并把这个全局变量设置为一个特殊标 记。如果输入的是“0”,则返回0,不会设置全局变量,这样当得到返回值0的时候,可以通过检查全局变量 得知输入究竟是非法输入还是字符串“0”.
值得注意的还有一点:如果字符串中含有“0”到“9”之外的字符,那么这样的输入也是非法的!!!
下面进行代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int status=0; //设置全局变量来记录是不是正常返回
int my_atoi(const char *str)
{
long long num = 0;
int flag = 1; //设置标记
assert(str);
while (*str==' ') //跳过字符串开头的空格
{
str++;
}
while (*str == '\0') //如果全部字符串中都是空格
{
status = 1; //将state设置成1,表示异常返回
return 0;
}
if (*str == '-') //跳过空格后,再判断有没有'-'和'+'
{
flag = -1; //如果是‘-’,则将flag设置成-1
str++;
}
else if (*str == '+')
{
str++;
}
while ((*str)&&(*str >= '0')&&(*str <= '9')) //判断是不是数字字符
{
if ((num>=(signed int)0x80000000) && (num<=(signed int)0x7FFFFFFF)) //判断有没有溢出
{
num = num * 10 + flag*(*str - '0'); //将标记位加上去
str++;
}
else //如果溢出,则跳出
break;
}
if (*str != '\0')
{
status=1;
return 0; //异常情况
}
return (int)num;
}
int main()
{
char *arr="0";
int ret=my_atoi(arr);
if (status == 1)
{
printf("异常返回\n");
}
printf("%d\n",ret);
system("pause");
return 0;
}