您的位置:首页

字符串转换成整数

2017-06-26 14:36 127 查看
微软面试题之中的一个,难度系数低。

题目描写叙述例如以下:输入一个表示整数的字符串,把该字符串转换成整数并输出。

比如输入字符串"345"。则输出整数345。

逻辑分析:

1、对于面试者来说,遇到这样的题,算是非常幸运的,比起思维灵活度,本题更加注重基础。也就是说,代码的稳定性,健壮性一定要好。对C/C++比較熟悉的读者应该非常快会想到一个函数:atoi,没错。标准库中的atoi就是将字符串转为整数的函数。尽管如此。但却非常少有人尝试去了解atoi这个函数的内部实现,窃以为,atoi的实现,事实上和str*系列函数同等重要。

2、说到稳定性,就要考虑几个easy引起问题的地方。函数模型int atoi(char* str);,那么第一点要考虑的。当然是str是否为空。另外,str中的字符仅仅可能存在三种情况:- | + | [0..9],假设存在其它字符,那么则视为非法字符。最后一点,也是最easy忽略的,要考虑溢出问题。

给出代码:
#include <stdio.h>
#include <limits.h>

int atoi(char *str)
{
bool neg = true;
char *p = str;
int num = 0;

if(str == NULL)
{
printf("字符串为空!你TM是在逗我吗?\n");
return 0;
}
if(*p == '-')
{
p++;
neg = false;
}else if(*p == '+')
{
p++;
}

while(*p != '\0')
{
if(*p>='0' && *p <= '9')
{
num = num * 10 + (*p - '0');
if(num > INT_MAX)
{
printf("溢出!\n");
return 0;
}
}
else
{
printf("错误!

含非法字符\n");
return 0;
}
p++;
}
if(neg == false)
num = -num;
return num;
}

int main()
{
char str[4][10] = {"123456789","+23","-45","XiaoJ8"};
for(int i=0; i<4;i++)
{
printf("%d\n",atoi(str[i]));
}
return 0;
}
输出:



3、乍看起来。我们好像完毕了任务,可是实际上。当我写完上述代码之后,立马反悔了。非常多读者应该也察觉到了。上述代码有一个非常严重的漏洞,我们都知道由于补码的形式存储。负整数的绝对值上限是要比正整数上限大1的,而我们推断的分支。显然漏掉了负上限。再细致考虑,就会发现,事实上判别代码从一開始就错了。并且是全然错了。高级语言不是汇编。我们无法通过CF,OF之类的(无符号当然是CF)标志位来判别。而在我们的程序中。num是永远不可能大于INT_MAX的,由于当num超过了这个值。则会自己主动溢出。变为一个非常小的值,再去比較显然没有意义。正确的处理。是要对照计算前后的num,假设计算后的值小于计算前,显然发生了溢出(想想为什么)。

第二种处理方式,就是从位数进行比較,显然后者略麻烦一些,倒也不失为一种思路。

代码不再纠正,兴许工作由读者完毕。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: