文章目录
atoi()函数
通过上述cplusplus和MSDN对atoi函数的介绍我们可以得出以下几个关键点
- 库函数: <stdlib.h>
- 形参:const char * str
- 返回值: int
- 作用:atoi函数是将一个字符串转化成一个整型并忽视字符串中的字符
举个例子
c
/* atoi example */
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atoi */
int main ()
{
int i;
char buffer[256];
printf ("Enter a number: ");
fgets (buffer, 256, stdin);
//fgets的功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。
i = atoi (buffer);
printf ("The value entered is %d. Its double is %d.\n",i,i*2);
return 0;
}
模拟实现
我们先整理一下cplusplus中 atoi 函数可能会发生的一些情况
- 分析 C 字符串 str,将其内容解释为整数,该整数以 type int 的值返回。
- 该函数首先根据需要丢弃尽可能多的空格字符( isspace)直到找到第一个非空格字符。然后,从此字符开始,采用可选的初始加号或减号,后跟尽可能多的以 10 为基数的数字,并将它们解释为数值。
- 字符串可以在构成整数的字符之后包含其他字符,这些字符将被忽略,并且对此函数的行为没有影响。
- 如果 str 中的第一个非空格字符序列不是有效的整数,或者由于 str 为空或仅包含空格字符而不存在此类序列,则不执行转换并返回零。
思路分析
- 第一步 :
通过循环将纯以10为基础的数字字符串转换为数字
因为输入的是字符,直接输出数字会转换为ASCII输出(字符1的ASCII码为49)
所以我们可以通过输出的数字剪掉字符0来得到最终数字
c
int s = 0;
while(*str != '\0')
{
s = s * 10 + *str - '0';
str++;
}
-
第二步
遇到空格符号、字符或其他类型时跳过
我们只需要用到 isdigit 函数判断是否为数字就行
-
第三步
开头符号问题
我们需要先循环掉一个字符前的所有空格,在判断出现的第一个字符是否为正负号,并通过flag来记录
-
第四步
判断字符指针是否为野指针,或者里面没有数据
存在这种情况时直接退出,并输出0
-
第五步
字符类型转整形,存在整形溢出的情况,需要定义为long long 型
同时因为我们要将字符串转化成整型,既然是整型,那么必然就会有范围,在头文件limits.h中有定义,我们就可以直接调出最大值最小值,如果这个数字大于INT_MAX或者小于INT_MIN就会返回0
代码呈现
具体步骤为
- 是否为野指针
- 是否为空指针
- 去除开头连续空格
- 判断正负号
- 是否为数字
- 判断是否超出整形范围
- 跳过非数字类型
- 判断这次转换是否非法(空指针、野指针)
c
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include<stdio.h>//大哥
#include<assert.h>//断言,判断是否为野指针
#include<limits.h>//INT_MAX和INT_MIN的头文件
enum Status
{
VALID, //0
INVALID //1
}status = INVALID;
int my_atoi(const char* str)
{
assert(str);//判断是否为野指针
long long s = 0;
if (*str == "\0")//判断字符是否为空
return 0;
while (*str == ' ')//循环掉所有的空格
{
str++;
}
int flag = 1;//判断正负
if (*str == '+')
{
flag = 1;
str++;
}
if (*str == '-')
{
flag = -1;
str++;
}
while (*str != '\0')//开始记录
{
if (isdigit(*str))//判断是否为数字
{
s = s * 10 + flag * (*str - '0');//正数累加,负数累减
if (s > INT_MAX)
{
s = INT_MAX;
break;
}
else if (s < INT_MIN)
{
s = INT_MIN;
break;
}
}
str++;
}
if(*str == '\0')//如果成功运行到最后一位就算完全字符转数字
status = VALID;
return (int)s;
}
//模拟实现atoi
int main()
{
char a[] = "123456acd123";
int b = my_atoi(a);
if (status == INVALID)
printf("非法转换:> %d", b);
else
printf("合法转换:> %d", b);
return 0;
}