atoi函数详解及其模拟实现——一篇文章带你彻底搞懂atoi

1.atoi函数的功能

在cplusplus中我们看到,atoi函数的功能是将数字字符串转换成int类型的整数!

atoi函数包含的头文件是:#include<stdlib.h>

比如:数字字符串“-123”被atoi转换成整数“-123”,将数字字符串“123”转换为“123”。

atoi函数使用示例:

我们在了解了atoi的基础功能之后,再来看看在这些特殊情况下,atoi函数的使用情况:

(1)该函数首先丢弃尽可能多的空白字符(如 isspace(信息空间))直到找到第一个非空白字符。然后,从这个字符开始,取一个可选的首字母符号后跟尽可能多的十进制数字,并将其解释为数值。比如:出现atoi(“      123”)的情况,一开始就遇到空格,就需要一直向后过滤,直到遇到数字字符1。

(2)字符串可以在构成整数的字符之后包含其他字符,这些字符将被忽略,并且不会影响此函数的行为。比如:出现atoi(“123a456”)的情况,从1开始转换直到遇到a这个非数字字符,终止转换。

(3)
如果中的第一个非空白字符序列字符串不是有效的整数,或者如果由于字符串为空或仅包含空白字符而不存在这样的序列,则不执行转换,并返回零。比如:atoi(“-a123”)或atoi(“”)等情况下,不执行转换,返回零。

(4)如果转换之后的数字大于int最大值,那么按照最大值算,相反,如果比最小的还小,那么就按照最小值算。在32位或64位系统中,int类型占用32位,其取值范围是从-2147483648到2147483647。

 2.atoi的模拟实现

在对函数的模拟实现之前,我们先来学习几个函数。

 (1)isspace

其功能是检查字符串是否为空白字符串,如果被检查的字符不是空白字符串,则返回值是0,反之返回一个非零的值。

该函数被包含的头文件是:

#include <ctype.h>

(2)isdigit 

 

检查字符是否为十进制数 ,如果被检查的字符不是十进制数字,该函数的返回值为0,反之,返回值为非零。

包含头文件是:

#include <ctype.h>

(3)对atoi的基础功能模拟:

 

对n = n * 10 + (*str - '\0')的分析:

 

(4)atoi具体功能的模拟实现

<1>根据第一部分对atoi函数在特殊情况下的功能的分析,我们可以依次补充基础代码。如下:

此时我们已经完成了atoi的大部分功能。 

​
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
int my_atoi(const char* str)
{
	assert(str);
	//用isspace函数向后过滤空白字符
	//isspace返回值不为0,代表是空格
	while (isspace(*str))
	{
		str++;
	}//走到这里str一定不是空格了
	if (*str == '\0')//空字符串问题
	{
		return 0;
	}
	//+-号问题
	int flg = 1;
	if (*str == '+')
	{
		flg = 1;
		str++;
	}//注意这里要用else if,不能用else
	else if(*str == '-')
	{
		flg = -1;
		str++;
	}
	long long n = 0;
	while (*str != "\0")
	{
		if (isdigit(*str))
		{//是数字字符==>返回值不为0
			n = n * 10 + (*str - '\0') * flg;
		}
		else//不是数字字符
		{
			return (int)n;
		}
		str++;
	}
	return (int)n;
}
int main()
{
	int ret = my_atoi("123");
	printf("&d\n", ret);
	return 0;
}

​

 <2>针对溢出问题

 要在判断完是数字字符后加上一段代码:

if (n > INT_MAX)
{
	n = INT_MAX;
}
if (n < INT_MIN)
{
	n = INT_MIN;
}

<3>合法转换和非法转换的问题

比如:在转换“123”时指针一直走到‘\0’,才返回的123,这种情况属于合法转换,但是对于“123a56”这种非数字字符,在指针走到a时就不会再向后走了,直接返回123,这种情况属于非法转换。

怎么区分非法转换和合法转换呢?

这里可以使用到枚举:创建一个枚举类型,初始化为非法的(因为非法的情况较多,合法的情况只有一种)

enum State
{
	VAILD,
	INVAILD//非法的
}State = INVAILD;//初始化为非法

区分合法转换与非法转换:合法转换在指针结束访问时,指向的是‘\0’,因此应在函数末尾处判断

是否合法:

if (*str == '\0')
{
	State = VAILD;//走到‘\0’就是合法转换
}

最后在main函数中用printf打印呈现。 

 3.终极代码展示

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<assert.h>
enum Status
{
	VAILD,
	INVAILD//非法的
}status = INVAILD;//初始化为非法
int my_atoi(const char* str)
{
	assert(str);
	if (*str == '\0')//空字符串问题
	{
		return 0;
	}
	//+-号问题
	//用isspace函数向后过滤空白字符
	//isspace返回值不为0,代表是空格
	while (isspace(*str))
	{
		str++;
	}//走到这里str一定不是空格了
	
	int flg = 1;
	if (*str == '+')
	{
		flg = 1;
		str++;
	}//注意这里要用else if,不能用else
	else if(*str == '-')
	{
		flg = -1;
		str++;
	}
	long long n = 0;
	while (*str != '\0')
	{
		if (isdigit(*str))
		{//是数字字符==>返回值不为0
			n = n * 10 + (*str - '0') * flg;
			if (n > INT_MAX)
			{
				n = INT_MAX;
			}
			if (n < INT_MIN)
			{
				n = INT_MIN;
			}
		}
		else//不是数字字符
		{
			return (int)n;
		}
		str++;
	}
	if (*str == '\0')
	{
		status = VAILD;//走到‘\0’就是合法转换
	}
	return (int)n;
}
int main()
{
	int ret = my_atoi("-123");
	if (status == VAILD)
	{
		printf("合法转换: n = %d\n",ret);
	}
	else
	{
		printf("非法转换: n = %d\n",ret);
	}
	return 0;
}

感谢各位的阅读,如果有哪里写的不对的地方,欢迎大家评论私信呦!!!

  • 13
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值