关于itoa和atoi,本来是很基本的函数,实现方式也不难,但是要考虑的异常情况有很多。搜集了很多资料,发现有很多写法,但很少有考虑所有异常输入的写法。
一些Linux库函数源码会提供,但是过于复杂,在这里,我整理了一下,得到下面的两个函数实现,大概考虑到了80%的异常输入,大概可以满足一般的面试要求。
#include<iostream>
using namespace std;
//错误输入和“0”都将返回0,前者置status为Invalid,后者置status为Valid
enum Status{Valid=0,Invalid};
int status=Valid;
//atoi的实现
int StrToInt(const char* str)
{
status=Invalid;
long long num=0;
if(str!=NULL&&*str!='\0')
{
//排除空格
while(*str==' ')
str++;
//判断正负
bool minus=false;
if(*str=='+')
str++;
else if(*str=='-')
{
str++;
minus=true;
}
while(*str!='\0')
{
if(*str>='0'&&*str<='9')
{
int flag=minus?-1:1;
num=num*10+flag*(*str-'0');
//溢出判断
if((!minus&&num>0x7FFFFFFF)||(minus&&num<(signed int)0x80000000))
{
num=0;
break;
}
str++;
}
else
{
num=0;
break;
}
}
if(*str=='\0')
{
status=Valid;
}
}
return num;
}
//itoa的实现
char* IntToStr(int num)
{
int sign = num;
int i = 0;
int j = 0;
char temp[100];
if(sign < 0)//如果是负数就去掉符号,将-1234转成1234
{
num = -num;
}
do//转成字符串,1234转成"4321"
{
temp[i] = num % 10 + '0';
num /= 10;
i++;
}while(num > 0);
if(sign < 0)//如果是负数的话,加个符号在末尾,如:"4321-"
{
temp[i++] = '-';
}
temp[i] = '\0';
//result保存结果
char *result=new char[i+1];
//将temp数组中逆序输入到result中
i--;
while(i >= 0)
{
result[j] = temp[i];
j++;
i--;
}
//字符串结束标识
result[j] = '\0';
return result;
}