详解atoi函数+模拟实现

浅谈C语言 专栏收录该内容
9 篇文章 3 订阅

前言:托更了这么久也不知道写啥,随便写写吧!模拟实现标准库的atoi函数(作用:将字符串转化为整形    )希望大家有所收获! 


目录

一.函数讲解

二.实例

三.模拟实现


 一.函数讲解

1.函数原型

2.函数作用

作用:将字符串转化为整形  


二.实例

#include<stdlib.h>
int main()
{
	printf("%d\n", atoi("1234"));
	printf("%d\n", atoi("12a34"));
	printf("%d\n", atoi("-1234"));
	printf("%d\n", atoi(""));
	printf("%d\n", atoi("0"));
	printf("%d\n", atoi("   -12a34"));
	return 0;
}

执行结果 


三.模拟实现

注意事项:

  • 由于接受传过来的字符串是不需要修改的,所以可以使用const进行修饰

  • 要考虑的情况

    • str为空NULL

    • str为空字符串

    • 前面有空白字符

    • 前面有正负号

    • 出现非数字字符

    • 数值太大


my_atoi(NULL);//空指针
my_atoi("");//空字符串  空字符串的长度为0  (strlen求)
my_atoi("0")//要和传空指针和空字符串情况进行区分
my_atoi("    1234");//前面有空格的情况
my_atoi("    +1234");//前面有正负号
my_atoi("    +1234abc")//含非数字字符
my_atoi("148194719751911");//超出范围,溢出

模拟实现思路

思路:

  • 由于要区分为0的情况,为了避免造成歧义。可以定义一个变量,判断是否为异常返回 ->溢出、空指针、空字符串都为异常返回

     enum State
     {
         VALID,  //正常返回
         INVALID //异常返回
     };
     enum State state = INVALID;     //先假设为异常返回
     //当然也可以不使用枚举,使用枚举只是更直观。使用1和0等也可以
  • 步骤1:先判断是否为空字符串,空指针

  • 步骤2:跳过空白字符

  • 步骤3:识别正负数

  • 步骤4:字符串转化为整数,遇到非数字字符的就停止转化,更改返回状态为正常返回,注意:还要在转化过程判断是否溢出,如果溢出,直接为异常返回

  • !!!最后,若一切正常,最后还是会遇到\0,此时为正常返回,将返回状态改为正常返回


enum State
{
    VALID,	//正常返回
    INVALID //异常返回
};
enum State state = INVALID; 	//先假设为异常返回
//注意:state为全局变量  state是变量,但是它的值是枚举常量,全局变量是为了在main函数中判断返回状态是否合法,如果state写在my_atoi函数内部,则只在该函数内有效
int my_atoi(const char* str)
{
    //str是空指针
    if(str == NULL)
    {
        //直接异常返回
        return 0;
    }
    //也可以直接断言 :assert(str);
    //str为空字符串->第一个字符为\0
    if(*str == '\0')
    {
        //异常返回
        return 0;
    }
    //跳过空白字符,如果str指向的是空白字符则进入循环
    while(isspace(*str))
    {
        str++;
    }
    //跳出循环时,str非空白字符
    //判断正负号
    int flag = 1;	//假设为正数
    if(*str =='+')
    {
        //注意!!!不要忘了str++往后走
        str++;
    }
    else if(*str == '-')
    {
        flag = -1;//负数
        str++;
    }
    //上述不可以使用if else  而是要if else-if ,因为不一定有正负号,所以flag也要定义为1,不能定义为0!
    //字符转化
    long long ret = 0;
    while(*str)
    {
        if(isdigit(*str))
        {
            ret = ret*10 + (*str - '0')*flag;
            //要判断是否溢出
            if(ret >INT_MAX || ret <INT_MIN)
            {
                return 0;//异常返回
            }
            str++;
        }
        else
        {
            //遇到非数值字符,正常返回,改状态
            state = VALID;//正常返回
            return (int)ret;//为了防溢出,定义的ret是long long类型,但是我们的返回类型是int类型,所以要强制类型转化
        }
    }
    //可能一切正常,纯数字字符,最后str指向\0,跳出循环,此时是合法的
    state = VALID;
    return  (int)ret;//为了防溢出,定义的ret是long long类型,但是我们的返回类型是int类型,所以要强制类型转化
}
int main()
{
    int ret = my_atoi("   13a4dw");
    //判断是否是合法返回
    if(state == VALID)
    {
        //合法返回
        printf("合法返回:值为:%d\n",ret);
    }
    else 
    {
        printf("异常返回:值为:%d\n",ret);
    }
    return 0;
}

  • 13
    点赞
  • 8
    评论
  • 7
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:鲸 设计师:meimeiellie 返回首页

打赏作者

芒果再努力

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值