C语言-atoi()库函数的模拟实现

文章目录


前言

本篇文章介绍c语言中库函数atoi()的使用,以及模拟实现库函数。


一、atoi()库函数的介绍及使用

1.1 atoi()库函数介绍

以下是cplusplus网站关于atoi()库函数的介绍。atoi()库函数

说明:

  • 首先,这个函数会将字符串前面的空格一一跳过,直到遇到非空格字符;这个非空字符分为以下情况

    • 如果非空字符为字母,则返回结果为0
      比如"abc123",转换得到0
    • 如果非空字符为'-',则会转换得到一个负整数且这个负整数没有超过int表示的范围,正常返回这个数;如果这个数超过了int型数据的表示范围,则返回-2147483648
      例如,
      "-12345",转换得到整型数值-12345
      "-123456789123456"转换得到-2147483648
    • 如果非空字符为'+'或者为数字字符,则会转换得到一个正整数且这个正整数没有超过int表示的范围,正常返回这个数;如果这个数超过了int型数据的表示范围,则返回2147483647
      例如,
      "+12345"转换得到整型数值12345
      "123456"转换得到整型数值12345
      "123456789123456"转换得到2147483647
  • 如果str指向的是一个空字符串或者只包含空格,则返回值为0.

  • 如果两个数字字符之间存在其他非数字字符,则转换非数字字符之前的数字字符。

    "123ab112",只会转换得到整型数值123

1.2 atoi()库函数使用

  • 负数转换

  • 负数溢出转换

  • 正数转换

  • 正数溢出转换

  • 包含非数字字符

    (1)数字字符后面包含其他字符

(2)数字前面包含非数字字符

  • 只包含非数字字符

二、atoi()库函数的模拟实现

2.1 函数设计

c 复制代码
函数名:StrToInt
函数返回值类型: int
函数参数类型: const char* str
int StrToInt(const char* str);

2.2 函数实现思路

  1. 函数指针的非空判断
c 复制代码
//指针的非空判断 利用断言
assert(str);
  1. 空字符串的判断
c 复制代码
//如果第一个字符为'\0',则表示字符串为空串
if('\0' == *str)
{
	return 0;
}
  1. 跳过字符串前面的空格字符
c 复制代码
//利用库函数提供isspace()函数判断
while(isspace(*str)) str++;
  1. 正数和负数的符合判断
c 复制代码
int flag = 1; //默认为正数
switch(*str)
{
case '-': flag = -1;
case '+': str++;
}
  1. 字符数字与整型数值的转换
c 复制代码
//1.如果溢出判断使用long long
long long ret = 0;
while(isdigit(*str))  //isdigit()函数为库函数
{
	ret = 10*ret + flag*(*str - '0');
	//溢出判断
	if(ret > INT_MAX)
	{
		return INT_MAX;
    }
    else if(ret < INT_MIN)
    {
    	return INT_MIN;
	}
	str++;
}
return  (int)ret;


//2. 如果溢出判断不使用long long
int ret = 0;
while(isdigit(*str))
{
	int ConvertDigit = *str - '0';
	if((ret > INT_MAX/10) || ((INT_MAX/10 == ret) && (ConvertDigit > 7)))
	{
		return flag > 0? INT_MAX:INT_MIN;
	}
	ret = ret*10 + ConvertDigit; 
}
return flag > 0 ? ret : -ret;

2.3 具体实现

  • 方法一(使用long long)
c 复制代码
#include<assert.h>
#include<limits.h>
#include<ctype.h>
//version 1.3 
int StrToInt(const char* str)
{
	//1. 空指针判断
	assert(str);
	//2. 空字符串判断
	if ('\0' == *str)
	{
		return 0;
	}

	//3. 去掉空格
	while (isspace(*str)) str++;

	long long ret = 0; //long long 用于判断转换结果是否超出int的表示范围
	int flag = 1; //用于判断是否为负数,默认为非负数
	//4. + - 判断
	switch (*str)
	{
		case '-': flag = -1;
		case '+': str++;
	}

	//转换操作
	while (isdigit(*str))
	{
		ret = ret * 10 + flag * (*str - '0');
		//5. 溢出判断
		if (ret > INT_MAX)
		{
			return INT_MAX;
		}
		if (ret < INT_MIN)
		{
			return INT_MIN;
		}
		++str;
	}

	return (int)ret;
}
  • 方法二(不使用long long)
c 复制代码
#include<assert.h>
#include<limits.h>
#include<ctype.h>

// version: 1.4 
// 溢出判断不使用long long
// 1. ConvertDigit = *str - '0'   ->得到字符转换成的数字
// 2. ret = ret*10 + ConvertDigit ->得到计算的结果,默认为正数,最后根据符号返回结果  
// 3. (正数溢出判断) 上一次 ret > INT_MAX/10   
//				 说明下一次计算的ret >= INT_MAX		   则正数溢出
// (负数溢出判断) 上一次 ret == INT_MAX/10 && ConvertDigit > 7  
//				 说明下一次相加 ret >= INT_MIN的绝对值   则负数溢出
//  INT_MAX = 2147483647   INT_MIN = -2147483647-1
// 最后根据flag返回结果  flag > 0 返回INT_MAX  否则返回INT_MIN    
// 4. flag > 0  直接返回 ret   flag < 0 返回-ret
int StrToInt(const char* str)
{
	//1. 空指针判断
	assert(str);

	//2. 空串判断
	if ('\0' == *str)
	{
		return 0;
	}

	//3. 清除空格
	while (isspace(*str)) str++;

	//4. 正负号判断
	int flag = 1;  //默认为正数
	switch (*str)
	{
		case '-': flag = -1;
		case '+': str++;
	}
	//5. 转换
	int ret = 0;
	while (isdigit(*str))
	{
		int ConvertDigit = *str - '0';
		//溢出判断
		if ((ret > (INT_MAX / 10)) || 
									(((INT_MAX/10) == ret) && (ConvertDigit > 7)))
		{
			return (flag > 0) ? INT_MAX : INT_MIN;
		}
		ret = ret * 10 + ConvertDigit;
		str++;
	}
	return flag > 0 ? ret : -ret;
}

2.4 测试

  • 负数

  • 负数溢出

  • 正数

  • 正数溢出

  • 包含非数字字符

    (1)数字字符后面包含非数字字符

    (2)数字字符前面包含非数字字符


总结

本篇文章介绍了库函数atoi()的使用,并使用不同的思路模拟实现atoi()。

相关推荐
珹洺3 小时前
C语言数据结构——详细讲解 双链表
c语言·开发语言·网络·数据结构·c++·算法·leetcode
.Cnn3 小时前
用邻接矩阵实现图的深度优先遍历
c语言·数据结构·算法·深度优先·图论
2401_858286113 小时前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
寻找码源4 小时前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp
带多刺的玫瑰6 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
陌小呆^O^6 小时前
Cmakelist.txt之win-c-udp-server
c语言·开发语言·udp
时光の尘7 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
-一杯为品-7 小时前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
爱摸鱼的孔乙己8 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan8 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法