简单模拟实现函数atoi

先分析一波:
  1. atoi的函数原型为:

    int atoi(   const char *str );  
    
  2. atoi函数的作用是:扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。

  3. 返回转换后的整型数;如果 str 不能转换成 int或者 str 为空字符串,那么将返回 0
  4. 如果需要模拟实现atoi,下面是我们需要注意的几个问题:
    1. 如果传入的串为空串,那么返回0,并且标记为非法。
    2. str字符串传入时,开始扫描,如果前面为空白字符,那么将这些位置跳过。
    3. 当空白字符全部跳过时,如果遇到正负号,那么转换开始,如果未遇到,默认为正数。
    4. 如果转换的过程中,数字溢出,那么返回0,并且标记返回值非法。
    5. 如果在转换的过程中遇到非数字字符,那么函数返回,并且返回值为当前以转化的值,标记返回值合法。如果遇到的第一个字符即为非数字字符,函数返回值为0,并标记为合法。
    6. 标记是通过定义的枚举类型的全局变量实现的,枚举的成员为:VALIDINVALID,标记的默认值为INVALID,因为在判断中大多数情况都是无效的值。
    7. 如果转换的值不合法,那么不对转化结果进行输出。
下面我们对上述问题逐一实现:
  • str的空串问题:
    if (*str == '\0')       //第一个字符即为\0  
        return 0;
  • str的空白字符问题:
    while (isspace(*str))            //头文件为ctype.h                     
    {
        str++;
    }
  • 正负号问题
    if (*str == '-')                                            
    {
        flag = -1;              //flag的值用来与新获取的数字相乘再与记录的变量相加。
        str++;
    }
    else if (*str == '+')
    {
        str++;
    }
  • 遇到非数字字符问题以及溢出问题
        if (isdigit(*str))                                    
        {
            ret = ret * 10 + (*str - '0') * (flag);                        
            //溢出问题
            if (ret > INT_MAX || ret < INT_MIN)
            {
                return 0;
            }
        }
        else
        {
            //字符中的非数字字符
            state = VALID;
            return (int)ret;
        }
上面即为出现各种情况的处理方法,下面我们只需要将这些方法结合到一起,就可以简易的实现atoi。
#include<stdio.h>
#include<assert.h>
#include<ctype.h>
#include<limits.h>
enum State              //标记返回的数值是否合法
{
    VALID,
    INVALID
};
static enum State state = INVALID;    //默认值为不合法
int my_atoi(const char *str)
{
    long long ret = 0; //要判断是否溢出,所以让值存储在比int大的类型中,与int能存储的最大值进行比较
    int flag = 1;               //区别正负值问题
    assert(str != NULL);         //空指针
    if (*str == '\0')            //空串
        return 0;
    //前面为空字符
    while (isspace(*str))            //头文件为ctype.h                     
    {
        str++;
    }
    //正负号问题
    if (*str == '-')                                            
    {
        flag = -1;
        str++;
    }
    else if (*str == '+')
    {
        str++;
    }
    while (*str)                                                   
    {
        //是否为数字字符问题 
        if (isdigit(*str))                                    
        {
            ret = ret * 10 + (*str - '0') * (flag);                        
            //溢出问题
            if (ret > INT_MAX || ret < INT_MIN)
            {
                return 0;
            }
        }
        else
        {
            //字符中的非数字字符
            state = VALID;
            return (int)ret;
        }
        str++;
    }
    state = VALID;
    return (int)ret;
}
int main()
{
    int ret = 0;
    char p[20] = {0};
    printf("Please input->_: ");
    scanf("%s", p);
    ret = my_atoi(p);
    if(state == VALID)    //对模拟实现的函数来说 如果转化值不合法,则不进行输出
        printf("my_atoi(p) = %d\n", ret);
    printf("atoi(p)    = %d\n", atoi(p));
    return 0;
}
函数运行效果:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

以上即为本篇博客所有内容,不足之处还望指正!
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值