atoi (ascii to integer),是把参数 str 所指向的字符串转换为一个整数(int类型)的库函数。
使用场景
引子:
有兴趣的朋友可以听我逐句翻译一下cpluscplus.com里的这段解释(要考六级了练一下):
将字符串转换为整型
解析C-字符串str,将它的所含物解释为一个整数,将这个整数作为int类型的值返回。
这个函数首先丢弃必要数量的空白字符(像isspace),直到第一个非空白字符被找到。然后,从这个字符开始,接受一个可选的初始正号或负号,后面跟着尽可能多的十进制数字,并将它们解释为数字值。
这个字符串能够在组成整数的字符后面容纳额外的字符,这些字符会被忽略且对这个函数的行为没有影响。
如果str中非空白字符的第一个序列不是一个有效整数,或者这个序列不存在因为str要么是空字符要么只含有空白字符,那就不发生转换并将0作为返回值。
参数
以一个整数形式开始的C-字符串。
返回值
成功情况下,这个函数返回被转换的int类型的整数。
如果被转换的值超出了int能代表的最大范围,会导致未定义的行为。如果有可能的话,可以参阅strtol,以获得更健壮的跨平台替代方案。
atoi函数介绍
头文件
#include<stdlib.h>
原型
int atoi(const char *str)
功能
把参数 str 所指向的字符串转换为一个整数(类型为 int 型)。
返回值
返回转换后的整数,如没有执行有效的转换,返回零。
注意
转换时会先跳过前面的空格字符,直到遇上数字或正负符号才开始转换。遇到非数字或'\0',结束转换,并将结果返回。如果第一个字符不是数字,就直接返回0;
使用案例
光说难以理解,写一段代码来感受一下这个函数的使用吧:
#include<stdio.h>
#include<stdlib.h>//atoi需要的头文件
int main()
{
char str1[] = "123star123";
char str2[] = "star123";
char str3[] = " -123";//注意负号
char str4[] = "123 456";//注意中间的空白字符
int r1 = atoi(str1);
int r2 = atoi(str2);
int r3 = atoi(str3);
int r4 = atoi(str4);
printf("%d %d %d %d\n", r1,r2,r3,r4);
return 0;
}
而这是我们输出的结果:
而还有更加特殊的情况:
如果给atoi传一个空指针(NULL),会发生下面的情况:
int ret = atoi(NULL);
printf("%d", ret);
程序直接崩溃了。
还有,字符串的数字大小超过了整型数字的取值范围:
可以看到,我们明明给的是2147483648,得到的结果却是2147483647,因为这是int最大能代表的值, 这是因为当字符串的数字大小超过了int类型的取值范围时,这个函数返回时会变为int的最大或最小值。
有了上面这些例子,关于atoi函数,我们可以总结出几个特点:
1.当字符串中的数字被非10进制字符隔开时,atoi函数会返回当前位置之前的数字;
2.atoi函数会根据字符串内容自动判断整数的正负;
3.atoi函数会自动跳过开头的空白字符;
4.当参数传入NULL时会报错;传入空字符串时,返回值为0;
5.当字符串的数字大小超过了整型数字的取值范围时,返回时会变为整型数据的最大或最小值;
atoi函数模拟实现
既然我们已经知道了这个函数的实现逻辑,我们就能根据这些实现逻辑,自己写出一个模拟的atoi函数:
#include<stdio.h>
#include<ctype.h>//isspace需要的头文件
#include<stdlib.h>
int my_atoi(const char* str)
{
if (str == NULL||'\0')//判断str为NULL或空白字符串的特殊情况
return 0;
while (isspace(*str))//处理开头的空白字符
{
str++;
}
int flag = 1;//flag来代表数字正负
if (*str == '+')
{
flag = 1;
str++;
}
else if (*str == '-')
{
flag = -1;
str++;
}
long long ret = 0;//用long long类型变量来存储字符串数字,因为字符串里的数字可能大于int的最大值
while (*str)//*str != '\0'
{
if (isdigit(*str))//如果这一位是10进制数
{
ret = ret * 10 + (*str - '0')*flag;
str++;
if (ret > INT_MAX)
return INT_MAX;//如果已经超出int最大范围了,就返回int类型最大值
if (ret < INT_MIN)
return INT_MIN;//如果已经小于int最大范围了,就返回int类型最小值
}
else//如果这一位遇到非10进制数就直接返回当前值
{
return (int)ret;//别忘记强转回int
}
}
return (int)ret;
}
vs运行效果参考:
那么到此,atoi函数的使用和模拟的讲解就结束了,祝阅读愉快。