天天看点

C++ 实现 atoi

我记得以前有一道题是这样的,让求从一到一百中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 = ;
    bool falg = false;

    while (*str == ' ')  // 当遇到空格时,不做处理
    {
        str++;
    }

    if (*str == '-' || *str == '+')  // 遇到正负号的时候,后面结果处理,
    {
        if (*str == '-')
            falg = true;
        str++;
    }

    while (*str >= '0'&&*str <= '9')   // 遇到数字字符的时候,将其转换成数字
    {
        s = s *  + *str - '0';
        str++;
        if (s<) 
        {
            s = ;
            break;
        }
    }
    return s*(falg ? - : );
}

//纯数字的转换
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 ;
}
           

对于字符的转换,atoi中只有数字字符、空格和正负号,那么我们就通过FunTest1()来测试一下我们写的atoi和库里的atoi相比,有没有什么问题。同时,那么要是转换的字符中有其他的字符怎么处理,比如:英文字符,那么同样我们也用一个函数来测试一下。

C++ 实现 atoi

小结:

通过结果显示:我们可以看到纯数字转换的atoi,我们实现的,和库里的是一样的,那么再看FunTest2():

当数字后面有其他的字符的时候,atoi的转换会终止。结果会显示一个我们之前转换的结果;即使其他字符的后面还有数字字符,也不会去处理;要是最开始就是其他字符,而不是数字字符的话,那么直接就会返回一个0。

继续阅读