我记得以前有一道题是这样的,让求从一到一百中9的个数,当时我是这样做的,首先分析一下9的位置,发现,它可能是个位也可能是十位。
所以我们就让其对10取余,然后结果和9比较一下,是否相等,这是个位的9,同时我们再让其除以10,结果和9比较,是否相等,这是十位的9。
麻烦不?当时我就想,要是将数字全部转换成字符,那么只需遍历一遍就行了。这个atoi可以实现,那么今天我们就来模拟一下atoi,看看它有哪些特性,还有哪些缺陷。
首先介绍一下atoi的转换过程,这样我们在写atoi_my的时候也容易一些:
atoi() 函数会扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\0’)才结束转换,并将结果返回。
#include<iostream>
using namespace std;
//模拟实现 atoi
int atoi_my(const char *str)
{
int s = 0;
bool falg = false;
while (*str == ' ') // 当遇到空格时,不做处理
{
str++;
}
if (*str == '-' || *str == '+') // 遇到正负号的时候,后面结果处理,
{
if (*str == '-')
falg = true;
str++;
}
while (*str >= '0'&&*str <= '9') // 遇到数字字符的时候,将其转换成数字
{
s = s * 10 + *str - '0';
str++;
if (s<0)
{
s = 2147483647;
break;
}
}
return s*(falg ? -1 : 1);
}
//纯数字的转换
void FunTest1()
{
char *s1 = "333640"; // 测试
char *s2 = "-12345"; // 测试负数转化
char *s3 = "123.3113"; // 测试浮点数的转化
char *s4 = "-8362865623872387698"; // 溢出
int sum1 = atoi(s1);
int sum_1 = atoi_my(s1);
int sum2 = atoi(s2);
int sum_2 = atoi_my(s2);
int sum3 = atoi(s3);
int sum_3 = atoi_my(s3);
int sum4 = atoi(s4);
int sum_4 = atoi_my(s4);
cout << "atoi: :" << sum1 << endl; //结果对比
cout << "atoi_my:" << sum_1 << endl;
cout << "atoi: :" << sum2 << endl;
cout << "atoi_my:" << sum_2 << endl;
cout << "atoi: :" << sum3 << endl;
cout << "atoi_my:" << sum_3 << endl;
cout << "atoi: :" << sum4 << endl;
cout << "atoi_my:" << sum_4 << endl<<endl;
}
void FunTest2()
{
char *s1 = "123ad"; //数字在前后面有其他字符
char *s2 = "123asd456"; //数字之间有其他字符
char *s3 = "asd123"; //数字前面有其他字符
int sum1 = atoi(s1);
int sum_1 = atoi_my(s1);
int sum2 = atoi(s2);
int sum_2 = atoi_my(s2);
int sum3 = atoi(s3);
int sum_3 = atoi_my(s3);
cout << "atoi: :" << sum1 << endl; //结果对比
cout << "atoi_my:" << sum_1 << endl;
cout << "atoi: :" << sum2 << endl;
cout << "atoi_my:" << sum_2 << endl;
cout << "atoi: :" << sum3 << endl;
cout << "atoi_my:" << sum_3 << endl;
}
int main()
{
cout << "FunTest1()->" << endl;
FunTest1();
cout << "FunTest2()->" << endl;
FunTest2();
system("pause");
return 0;
}
对于字符的转换,atoi中只有数字字符、空格和正负号,那么我们就通过FunTest1()来测试一下我们写的atoi和库里的atoi相比,有没有什么问题。同时,那么要是转换的字符中有其他的字符怎么处理,比如:英文字符,那么同样我们也用一个函数来测试一下。
小结:
通过结果显示:我们可以看到纯数字转换的atoi,我们实现的,和库里的是一样的,那么再看FunTest2():
当数字后面有其他的字符的时候,atoi的转换会终止。结果会显示一个我们之前转换的结果;即使其他字符的后面还有数字字符,也不会去处理;要是最开始就是其他字符,而不是数字字符的话,那么直接就会返回一个0。