字符串转数字atoi的重新编写及注意事项

字符串转数字看似很简单,其实很多细节需要把握,这里涉及到代码完整性:功能测试、边界检测和负面测试。如果要把所有的细节都考虑到是不太容易的。

本博客启发于剑指offer的最后一章的第一个面试案例。

我想大家都知道用n=n*10+c-‘0’的方式来进行转换,这里就直接进行分析了。

功能测试:

出现+-号,能否正确识别并计算出正确结果。

边界检测:

如果发生溢出情况怎么办,字符串超出了int范围?

负面检测:

1、字符串为空“”

2、输入指针为NULL

3、含有非数字字符

4、开头的+、-号之后接着'\0'

5、小数点(新添加,代码未实现)


由于可能出现的负面输入以及溢出情况,我们需要对结果进行判断,这里介绍一下三种错误处理方式:返回值、全局变量、异常。

返回值:和系统API一致; 但是不能方便的使用返回结果,并且会有二义性。

全局变量:用全局变量表示错误状态,能方便使用结果; 但是程序员可能会忘记检查全局变量。

异常:可以为不同的出错原因定义不同该异常类型,逻辑清晰明了; 有些语言不支持,同时对性能有一定程度上的负面影响。


这里附上全局变量和异常处理的两种代码供参考:

全局变量:

enum Status{Valid = 0, Invalid, OutOfRange};
int g_status = Invalid;
int atoi(char* str)
{
	if(str != NULL && *str != '\0') 
	{
		g_status = Invalid;
		//这里用long long是为了判断它的越界;
		long long num = 0;

		char *tmp = str;
		int flag = 1;
		//判断开头的符号;
		if(*tmp == '-')
		{
			flag = -1;
			++tmp;
		}
		else if(*tmp == '+')
			++tmp;
		//以免只有符号没有数字;
		if(*tmp != '\0')
		{
			while(*tmp != '\0')
			{
				if(*tmp >= '0' && *tmp <= '9')
				{
					//如果num不是long long,这里就需要多计算一次;
					num = num*10 + flag * (*tmp - '0');
					if(flag && num > 0x7FFFFFFF)
					{
						g_status = OutOfRange;
						return 0;
					}
					if(flag == 0 && num < 0x80000000)
					{
						g_status = OutOfRange;
						return 0;
					}
				}
				else
				{
					return 0;
				}

			}
		}
		g_status = Valid;
		return num;
	}	
}

异常:

int atoi(char* str)
{
	if(str != NULL && *str != '\0') 
	{
		//这里用long long是为了判断它的越界;
		long long num = 0;

		char *tmp = str;
		int flag = 1;
		//判断开头的符号;
		if(*tmp == '-')
		{
			flag = -1;
			++tmp;
		}
		else if(*tmp == '+')
			++tmp;
		//以免只有符号没有数字;
		if(*tmp != '\0')
		{
			while(*tmp != '\0')
			{
				if(*tmp >= '0' && *tmp <= '9')
				{
					//如果num不是long long,这里就需要多计算一次;
					num = num*10 + flag * (*tmp - '0');
					if(flag && num > 0x7FFFFFFF)
						throw range_error("Error: out of range!");					
					if(flag == 0 && num < 0x80000000)
						throw range_error("Error: out of range!");					
				}
				else
				{
					throw invalid_argument("Error: invalid input!");
				}

			}
		}
		else 
			throw invalid_argument("Error: invalid input!");

		return num;
	}
	else
		throw invalid_argument("Error: invalid input!");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值