atoi函数详解

atoi函数使用方法

在c++官网中是这样介绍atoi函数的

通俗的讲就是把字符串中的字符数字转换为整形数字,遇到空格就跳过,如果在字符串开始遇到不是有效的整数比如说abc就直接返回0,如果遇到像这种情况123abc345这个就只返回123,这个函数包含在stdlib.h头文件里我们来试一下

c 复制代码
# define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
# include<stdlib.h>

int main()
{
	char arr[] = { "   123abc345" };
	char arr1[] = { "  abcd123" };
	char arr2[] = { "  -123sdf" };
	char arr3[] = { "  @aq1234" };
	int ret = atoi(arr);
	int ret2 = atoi(arr1);
	int ret3 = atoi(arr2);
	int ret4 = atoi(arr3);
	printf("%d\n%d\n%d\n%d\n", ret,ret2,ret3,ret4);
	return 0;
}

模拟实现atoi

在模拟实现之前我们要考虑清楚有几种情况,第一种就是传的字符串是空指针,第二种是开头有空格需要跳过,第三种就是开头是除开0到9的字符,第四种就是开头是数字字符是正数还是负数,还有就是合法转换和非法转换。下面是代码

c 复制代码
# define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
# include<ctype.h>
# include<stdlib.h>
# include<assert.h>
enum State
{
	VAILD,//不非法的 
	INVAILD//非法的
} state = INVAILD;

int my_atoi(const char* str)
{
	assert(str != NULL);
	if (*str == '\0')
	{
		return 0;
	}
	while (isspace(*str))
	{
		str++;
	}
	int flag = 1;
     if(*str == '-')
	{
		flag = -1;
		str++;
	}
	 if (*str == '+')
	 {
		 flag = 1;
		 str++;
	 }
	long long ret = 0;
	while (*str != '\0')
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + (*str - '0')*flag;
			if (ret > INT_MAX)
			{
				return INT_MAX;
			}
			 if (ret < INT_MIN)
			{
				return INT_MIN;
			}
		}
		else
		{
			return (int)ret;
		}
		str++;
	}
	if (*str == '\0')
	{
		state = VAILD;
	}
	return (int)ret;
}
int main()
{
	char str[] = { "  -123abc34" };
	int ret = my_atoi(str);
	if (state == VAILD)
	{
		printf("合法转化:%d\n", ret);
	}
	else
	{
		printf("不合法转化:%d\n", ret);
	}
	return 0;
}

分布讲解

c 复制代码
nt my_atoi(const char* str)
{
	assert(str != NULL);
	if (*str == '\0')
	{
		return 0;
	}
	while (isspace(*str))
	{
		str++;
	}
	int flag = 1;
     if(*str == '-')
	{
		flag = -1;
		str++;
	}
	 if (*str == '+')
	 {
		 flag = 1;
		 str++;
	 }

这一段代码就是解决如果 字符串中的第一个非空格字符序列不是有效的整数,或者由于空或仅包含空格字符而不存在此类序列,则不执行转换并返回零。还有遇到空格字符跳过的情况,这样用了一个函数isspace 这个函数就是用来判断是不是空格字符,并且断言了一下传过来的字符串是不是空指针,

如果都不是就进入下面的if语句这里主要就是判断是正数还是负数,其实正数是不需要判断前面是不是有加号的,这样做就主要是为了防止有这样的字符串传过来像+123这种情况,这里设置了一个flag变量来判断是正数还是负数。

c 复制代码
long long ret = 0;
while (*str != '\0')
{
	if (isdigit(*str))
	{
		ret = ret * 10 + (*str - '0')*flag;
		if (ret > INT_MAX)
		{
			return INT_MAX;
		}
		 if (ret < INT_MIN)
		{
			return INT_MIN;
		}
	}
	else
	{
		return (int)ret;
	}
	str++;
}

这段代码就除开那上面那些情况来进入下一步判断,首先我们设置了一个长整形来防止整形溢出,然后进入while循环当str字符串解引用不是字符串结尾\0的时候进行,下面进入if语句如果对字符串解引用是一个数字,这里用了一个isdigit函数来判断是否为数字。

c 复制代码
ret = ret * 10 + (*str - '0')*flag;

这是一个数学公式用来把字符123变成数字123的,假如字符1想变成数字1就那字符一减去字符0,他们之间的ascii码差值就是数字1,在下面两个if就是一种比较特殊的情况了,在atoi函数定义中如果返回的数字大于intmax和小于intmin就直接返回intmax和intmin,最后那个else就是遇到除开0到9字符遇到其他字符就直接返回了,最后str指针自增1,我们来看看开头设置的一个枚举

c 复制代码
enum State
{
	VAILD,//不非法的 
	INVAILD//非法的
} state = INVAILD;

这里就是用来判断返回的到底是合法还是非法的,合法的就是想把字符串中所有的数字都转换完了的就相当于把字符串都遍历了一遍,字符串指针走到了字符结尾非法的就是没有遍历完,没有走到字符串结尾。这里我们首先把他赋值为非法的

c 复制代码
if (*str == '\0')
{
	state = VAILD;//这里就是判断字符串指针走没走完
}
c 复制代码
if (state == VAILD)
{
	printf("合法转化:%d\n", ret);
}
else
{
	printf("不合法转化:%d\n", ret);
}

根据返回值来判断打印。

相关推荐
DARLING Zero two♡3 小时前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
QAQ小菜鸟4 小时前
一、初识C语言(1)
c语言
何曾参静谧4 小时前
「C/C++」C/C++ 之 变量作用域详解
c语言·开发语言·c++
互联网打工人no14 小时前
每日一题——第一百二十一题
c语言
朱一头zcy6 小时前
C语言复习第9章 字符串/字符/内存函数
c语言
此生只爱蛋6 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
何曾参静谧6 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
lulu_gh_yu7 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
~yY…s<#>8 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
EricWang135810 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端