atoi函数的实现

最近看完Linux线程然后在看网络编程,但是网络编程新概念太难了,就看剑指offer这个书缓缓。里面由关一个atoi函数实现的问题感觉非常有趣,就介绍给大家。

       #include <stdlib.h>

       int atoi(const char *nptr);

atoi() 函数会扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\0’)才结束转换,并将结果返回。返回转换后的整型数;如果 str 不能转换成 int 或者 str 为空字符串,那么将返回 0。

下面是四种atoi的实现,代码的注释将对这集中方法进行一一评析

#include<stdio.h>
#include<string.h>

#define bool int
#define false 0
#define true  1
enum Status{kValid=0,kInvalid};
int g_nStatus=kValid;

int StrToInt_1(const char *str)
{
    int number=0;
    while(*str!=0)
    {
        number=number*10+*str-'0';
        ++str;
    }
    return number;
}
/*
如果让大家来写,估计大部分人都会觉得这么简单,简直so easy,其实不然,加入我们输入的为空字符串,那么在gcc下直接会核心转储
*/
int StrToInt_2(const char *str)
{
    if(str==NULL)
        return 0;
    int number=0;
    while(*str!=0)
    {
        number=number*10+*str-'0';
        ++str;
    }
    return number;
}
/*
这个算是对StrToInt_1的一个优化吧,处理了如果为空字符串的情况
但是,假如恰巧函数的参数为0",那么究竟是我们输入的字符串为空串呢,还是字符串为空呢,我们无法根据函数的返回值去判断参数是否符合要求。同时,该函数还未考虑到字符串中的正负号问题。
*/
int StrToInt_3(const char *str)
{
    g_nStatus=kInvalid;
    int num=0;
    if(str!=NULL)
    {
        const char* digit=str;
        bool minus=false;
        if(*digit=='+')
            digit++;
        else if(*digit=='-')
        {
            digit++;
            minus=true;
        }
        while(*digit!='\0')
        {
            if(*digit>='0'&&*digit<='9')
            {
                num=num*10+(*digit-'0');
                digit++;
            }
            else
            {
                num=0;
                break;
            }
        }
        if(*digit=='\0')
        {
            g_nStatus=kValid;
            if(minus)
                num=0-num;
        }

    }
    return num;
}
/*
该函数优化了StrToInt_2,加入了全局变量,若输入字符串为非法输入则全局变量g_nStatus为kInvalid,同时函数结束。并且加入了处理正负号的步骤但是没有考虑到数据溢出的问题,同时还未考虑到字符串为"","+","-"的这些情况。
*/
long long StrToIntCore(const char* digit,bool minus)
{
    long long num=0;
    while(*digit!='\0')
    {
        if(*digit>='\0'&&*digit<='9')
        {
            int flag=minus?-1:1;
            num=num*10+flag*(*digit-'0');
            if(!minus&&num>0x7fffffff||(minus&&num<0x80000000))
            {
                num=0;
                break;
            }
            digit++;
        }
        else
        {
            num=0;
            break;
        }
    }
    if(*digit=='\0')
        g_nStatus=kValid;
    return num;
}

int StrToInt_4(const char *str)
{
    g_nStatus=kInvalid;
    long long num=0;
    if(str!=NULL&&*str!='\0')
    {
        bool minus=false;
        if(*str=='+')
            str++;
        else if(*str=='-')
        {
            str++;
            minus=true;
        }
        if(*str!='\0')
            num=StrToIntCore(str,minus);
    }
    return num;
}
/*
这个就属于终极版了,首先考虑到了空串,"","+","-"的问题,同时还处理了溢出的问题
*/
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值