atoi函数详解及模拟实现

本文详细介绍了C语言中的atoi函数,包括其功能、使用规则,以及如何模拟实现处理超出int范围的情况。着重讲解了字符串解析、符号处理和边界条件处理等要点。
摘要由CSDN通过智能技术生成

atoi函数详解及模拟实现

函数详解

atoi函数包含在头文件 <stdlib.h>

int atoi(const char* str);

atoi将字符串str中的数字字符解释成整数以int类型的值返回。

举个例子:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("%d\n", atoi("123abc"));
    return 0;
}

打印结果是:

在这里插入图片描述

说到这,我们会想如果传入的字符串是类似"abc123ff567"这样的又该打印什么呢?是123还是123567,还是其他的。

答案是0。


接下来我们介绍一下atoi函数使用的一些注意事项和规则:

  • 如果传入的是NULL,会直接报错。

  • 如果是空字符串,直接返回0。

  • 如果转换后的值超出 int 的可表示值范围,则会导致未定义的行为。

​ 头文件 <limits.h> 内规定了int类型的最大值
在这里插入图片描述
除此之外,

atoi函数会先自动跳过所有空白字符,直到找到第一个非空字符,根据第一个非空字符,有如下规则:

  • 为数字字符,则继续寻找后面连续的数字字符,直到找到非数字字符,转换之前的数字字符
  • 为非数字字符,返回0。不过有特殊情况,如果第一个非空字符为’+‘或’-‘且后面的一位是数字字符,那么’+‘、’-'号作为后面连续数字字符转换后的符号,然后转换数字字符,直到找到非数字字符。例如" +123ggg"转换后为123(省略+号)、" -342opp"转换后为-342

我们看几组例子:

#include <stdlib.h>
#include <stdio.h>
int main()
{
    printf("%d\n", atoi(""));//空字符串
    printf("%d\n", atoi("a123"));//首非空字符不为数字字符
    printf("%d\n", atoi(" +-123end"));//首非空字符为'+',但是它后面一个字符不是数字字符
    printf("%d\n", atoi(" - 123end"));//首非空字符为'-',但是它后面一个字符不是数字字符
    printf("%d\n", atoi(" +12345678900"));//未定义的行为,返回值不是我们想要的
    printf("%d\n", atoi(" -12345678900"));//未定义的行为,返回值不是我们想要的
    printf("%d\n", atoi("   +123end"));//首非空字符为'+'且后面一个字符是数字字符
    printf("%d\n", atoi("  -12 3end"));//注意中间的空白字符不会跳过
    return 0;
}

打印结果为:

在这里插入图片描述

模拟实现

//我们将转换后超出int范围情况的返回值设置为0,以此表示未定义行为。
#include <limits.h>
#include <stdlib.h>
#include <ctype.h>

int my_atoi(const char* str)
{
    assert(str);//NULL情况
    long long ret = 0;
    int flag = 1;//标识符号
    while (isspace(*str))//跳过空白字符
    {
        str++;
    }
    if (*str == '\0')//判断为空字符串则返回0
        return 0;

    while (*str != '\0')
    {
        //第一个非空字符不为数字字符的特殊情况
        if (*str == '-' && isdigit(*(str + 1)))
        {
            flag = -1;
            str++;
        }
        else if (*str == '+' && isdigit(*(str + 1)))
        {
            flag = 1;
            str++;
        }
        //非空字符不为数字字符且不满足特殊情况
        else if (!isdigit(*str))
        {
            return 0;
        }
        //找到数字字符开始转换
        else
        {
            while (isdigit(*str))
            {
                ret = ret * 10 + (*str - '0');
                if (ret > INT_MAX || ret < INT_MIN)
                    return 0;
                str++;
            }
            ret = ret * flag;
            return (int)ret;
        }
    }
}


int main()
{
    printf("%d\n", my_atoi(""));
    printf("%d\n", my_atoi("a123"));
    printf("%d\n", my_atoi(" +-123end"));
    printf("%d\n", my_atoi(" - 123end"));
    printf("%d\n", my_atoi(" +12345678900"));
    printf("%d\n", my_atoi(" -12345678900"));
    printf("%d\n", my_atoi("   +123end"));
    printf("%d\n", my_atoi("  -12 3end"));
    return 0;
}

测试结果是:

在这里插入图片描述
为了方便观看,把模拟实现的函数单独拿出来。

int my_atoi(const char* str)
{
    assert(str);
    long long ret = 0;
    int flag = 1;
    while (isspace(*str))
    {
        str++;
    }
    if (*str == '\0')
        return 0;

    while (*str != '\0')
    {
        if (*str == '-' && isdigit(*(str + 1)))
        {
            flag = -1;
            str++;
        }
        else if (*str == '+' && isdigit(*(str + 1)))
        {
            flag = 1;
            str++;
        }
        else if (!isdigit(*str))
        {
            return 0;
        }
        else
        {
            while (isdigit(*str))
            {
                ret = ret * 10 + (*str - '0');
                if (ret > INT_MAX || ret < INT_MIN)
                    return 0;
                str++;
            }
            ret = ret * flag;
            return (int)ret;
        }
    }
}

以上就是对于atoi函数的全部介绍了。

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值