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

来源:互联网 发布:软件商业计划书模板 编辑:程序博客网 时间:2024/05/22 06:24

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

本博客启发于剑指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;}elsethrow invalid_argument("Error: invalid input!");}


0 0