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()。

相关推荐
双叶83610 天前
(C语言)Map数组的实现(数据结构)(链表)(指针)
c语言·数据结构·c++·算法·链表·哈希算法
不会kao代码的小白10 天前
C指针总结复习(结合deepseek)
c语言
XiaoCCCcCCccCcccC10 天前
C语言数组介绍 -- 一维数组和二维数组的创建、初始化、下标、遍历、存储,C99 变长数组
c语言·数据结构·算法
岁忧10 天前
第十六届蓝桥杯C/C++程序设计研究生组国赛 国二
c语言·c++·算法·蓝桥杯
一ge科研小菜鸡10 天前
编程语言的设计之道:从底层控制到表达自由
java·c语言·c++·python
天若有情67310 天前
技术逐梦之旅:从C语言到Vue的成长之路
c语言·开发语言·vue.js
Jess0710 天前
队的简单介绍
c语言
攻城狮7号10 天前
【AI时代速通QT】第二节:Qt SDK 的目录介绍和第一个Qt Creator项目
c语言·c++·qt·跨平台
jz_ddk10 天前
[学习] C语言<string.h>中字符串函数全解析
c语言·开发语言·学习