【C语言】C语言 atoi 函数解析

文章介绍了C语言中的atoi函数,用于将字符串转换为整型数值。它会跳过开头的空格,遇到非数字字符则停止转换。文章提供了atoi函数的使用示例,并给出了C语言的自我实现版本,以及更严谨的C++实现。强调了对函数特性和限制的理解对于有效使用的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


  •   🧑‍🎓个人主页:简 料

  •   🏆所属专栏:C语言

  •   🏆个人社区:越努力越幸运社区

  •   🏆简       介:简料简料,简单有料~在校大学生一枚,专注C/C++/GO的干货分享,立志成为您的好帮手 ~


C/C++学习路线 (点击解锁)(●’◡’●)
❤️C语言
❤️初阶数据结构与算法
❤️C++
❤️高阶数据结构
❤️Linux系统编程与网络编程

前言

  • 对于atoi函数大家可能会有些陌生,不过当你选择并阅读到这里时,请往下阅读,我相信你能对atoi函数熟悉
  • 该函数的头文件为 <stdlib.h><cstdlib>

atoi函数的介绍

此函数的功能是将数字字符的字符串转化为字面上的整型返回,例如:

char arr[] = "1234";
将”1234-> 1234(int)

以下是函数原型:
在这里插入图片描述

在这里插入图片描述

要注意的点:

  • 如果字符串从开头就有连续的空格字符,则跳过这些连续的空格字符,找到不是空格的字符。
    1. 如果跳过这些空格字符后的第一个字符不是数字字符,则直接返回0;
    2. 如果跳过这些空格字符后的第一个字符是数字字符,则从这个数字字符开始转换,并向后找连续的数字字符转换 ,如果连续中断,找到不是数字字符的字符,则在此截断寻找,返回前面已经转换好的连续的数字字符字面整型值。(这里截断向后寻找后,不管后面有没有数字字符函数都不管)

在这里插入图片描述

  • 如果字符串首元素不是空格字符
    1. 如果第一个字符不是数字字符,直接返回0
    2. 如果第一个字符是数字字符, 则从这个数字字符开始转换,并向后找连续的数字字符转换 ,如果连续中断,找到不是数字字符的字符,则在此截断寻找,返回前面已经转换好的连续的数字字符字面整型值。

在这里插入图片描述

  • 如果字符串全部为空格字符,返回0;如果为空字符串,返回0;

atoi函数的使用

  • 有了上面的介绍,使用的意图变得明显,使用起来也就随手就来了。

例如:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	char a[] = "";
	char b[] = "     ";
	char c[] = "66666";
	char d[] = "    @. 66ab";
	char e[] = "    6666@qq.com";
	char f[] = "520hehe";
	char g[] = "i love you 555";

	printf("%d\n", atoi(a));
	printf("%d\n", atoi(b));
	printf("%d\n", atoi(c));
	printf("%d\n", atoi(d));
	printf("%d\n", atoi(e));
	printf("%d\n", atoi(f));
	printf("%d\n", atoi(g));

	return 0;
}

在这里插入图片描述

看上的结果,是不是就与介绍当中的点都对应起来了呢?

atoi函数的自我实现

有了上面的铺垫,我们已经了解了该函数的特性,所以接下来的实现也就变的简单了

  1. 跳过空格字符(也可能没有,就不跳直接开始判断转换);
  2. 跳过后开始判断转换;
  3. 无论何种方式开始判断第一个字符,如果不是数字字符,直接返回0。
#include <stdio.h>
#include <assert.h>

// 数字ASCLL码值范围为 48—57

int my_atoi(const char* str)
{
	assert(str);

	const char* tmp = str;
	while (*tmp == ' ')  // 跳过空格字符
		tmp++;
	
	int num = 0; // 转换数字字符值的接收变量

	// 如果是数字字符,就进来,到不连续处就停止
	while (*tmp <= 57 && *tmp >= 48)  
	{
		num = num * 10 + (*tmp - '0');

		if (*(tmp + 1) < 48 || *(tmp + 1) > 57)
		{
			return num;
		}

		tmp++;
	}

	// 如果开始判断的字符不是数字字符,前面的循环不进去,这里直接返回0
	return 0;
}

int main()
{
	char a[] = "";
	char b[] = "     ";
	char c[] = "66666";
	char d[] = "    @. 66ab";
	char e[] = "    6666@qq.com";
	char f[] = "520hehe";
	char g[] = "i love you 555";

	printf("%d\n", my_atoi(a)); // 0
	printf("%d\n", my_atoi(b)); // 0
	printf("%d\n", my_atoi(c)); // 66666
	printf("%d\n", my_atoi(d)); // 0
	printf("%d\n", my_atoi(e)); // 6666
	printf("%d\n", my_atoi(f)); // 520
	printf("%d\n", my_atoi(g)); // 0

	return 0;
}

附:C++完整无缺版自我实现

前面C语言实现的atoi函数不够严谨,这里用c++实现严谨的atoi函数

class Solution {
public:
    int myAtoi(string s) {
        int flag = 1; // 操作正负数

        reverse(s.begin(), s.end());  // 先逆置
        while (s.size() > 1 && s.back() == ' ') s.pop_back(); // 除去前导‘0’ ,如果全是‘0’保留一个‘0’返回
        if (s.back() == '-') flag = -flag, s.pop_back(); // 利用flag来控制正负情况
        else if (s.back() == '+') s.pop_back();

        if (s.back() < 48 || s.back() > 57) return 0;  // 前面的工作完成后开始判断第一个位置是不是数字字符

        long long ret = 0;  // 怕存爆整型
        while (s.size() > 0)
        {
        	// 这一步如果存的时候就已经超过了int最大或小于最小,直接返回最大或最小
            if ((int)ret != ret) 
                if (ret * flag < 0) return INT_MIN;
                else return INT_MAX;
                
            if (s.back() >= 48 && s.back() <= 57)
            {
                // 每操作一次就删除那个数字字符
                ret = ret * 10 + (s.back() - '0');
                s.pop_back();
            }
            else
            {
            	// 找到第一个不是数字字符就跳出
                break;
            }
        }
        
        ret *= flag;

        if ((int)ret != ret)
            if (ret < 0) return INT_MIN;
            else return INT_MAX;
        else return (int)ret;
    }
};

写在最后

相信你已经对这个函数了如指掌了,认识掌握的函数越多,当然是没有坏处只有好处的。经过对atoi函数的学习,我相信你也会感觉到这个函数有好处也有缺陷,不过得用且用吧,在用的时候一定要脑子清醒,不要到头来骂这个函数,哈哈哈哈。

感谢阅读本小白的博客,错误的地方请严厉指出噢!

<think>好的,我现在需要回答用户关于C++中atoi函数的问题。首先,我要确认自己对atoi的理解是否正确。atoi是C标准库中的一个函数,用于将字符串转换为整数。它定义在<stdlib.h>头文件中,所以在C++中应该包含<cstdlib>来使用它。不过,用户可能是在C++代码中调用这个函数,所以需要说明它在C++中的使用方式。 接下来,我应该回忆函数的原型:int atoi(const char *str);。这个函数接受一个以空字符结尾的字符串,然后尝试将其解析为int类型的整数。如果字符串以有效的数字开头,函数会转换并返回对应的整数值;如果字符串开头不是数字或没有可转换的部分,就返回0。另外,如果转换后的值超出int的范围,行为是未定义的,这一点需要特别提醒用户注意潜在的问题。 然后,我需要考虑用户可能的疑问点,比如函数的使用场景、返回值的情况、以及安全性的问题。例如,atoi不会检测错误,如果传入无效的字符串,比如“abc”,它会返回0,但这样无法区分是真正的0还是转换失败。此外,溢出处理的问题,C++标准中没有定义,可能导致不可预测的结果,这时候可能需要推荐更安全的替代函数,比如strtol或者C++中的stoi,后者会抛出异常,更适合需要错误处理的场景。 还要举例说明atoi的用法,比如传入“1234”会返回1234,传入“12ab34”会返回12,而传入“abc”返回0,这样用户能直观地理解函数的行为。同时,对比C++中的字符串处理,比如使用string类的stoi方法,说明不同之处,比如是否需要处理异常等。 另外,需要指出atoi的局限性,比如只能处理十进制,不能处理其他进制,而像strtol则可以指定基数。同时,强调在C++中,如果可能的话,推荐使用更现代的C++特性,如stringstream或stoi,以提高类型安全和错误处理的能力。 可能用户在使用atoi时遇到了问题,比如转换失败或者溢出,这时候需要解释可能的原因,并提供解决方案。例如,当字符串为空或者不合法时,如何检测这些情况,或者如何处理大数导致的溢出问题。 最后,总结atoi的适用场景,比如在简单的、不需要复杂错误处理的场合,或者遗留代码中使用。但在新代码中,尤其是对安全性和健壮性要求较高的情况下,建议使用替代方法。</think>在C++中,`atoi` 是一个用于将**字符串转换为整数**的C标准库函数,定义在 `<cstdlib>` 头文件中。以下是逐步解析: --- ### 1. 函数原型 ```cpp int atoi(const char* str); ``` - **参数**:接受一个以空字符(`\0``)结尾的C风格字符串。 - **返回值**:转换成功时返回对应的 `int` 值,失败时返回 `0`。 --- ### 2. 工作原理 1. **跳过空白字符**:自动忽略字符串开头的空格(如空格、制表符等)。 2. **解析符号**:识别 `+` 或 `-` 符号(可选)。 3. **转换数字**:从第一个非空白字符开始,连续解析十进制数字,直到遇到非数字字符为止。 4. **终止条件**:遇到无效字符或字符串末尾时停止解析。 --- ### 3. 示例 ```cpp #include <cstdlib> #include <iostream> int main() { const char* str1 = "12345"; const char* str2 = " -678"; const char* str3 = "3.14abc"; const char* str4 = "invalid"; std::cout << atoi(str1) << std::endl; // 输出: 12345 std::cout << atoi(str2) << std::endl; // 输出: -678 std::cout << atoi(str3) << std::endl; // 输出: 3(遇到非数字字符停止) std::cout << atoi(str4) << std::endl; // 输出: 0(完全无法转换) } ``` --- ### 4. 注意事项 - **无错误检查**:无法区分 `"0"` 和无效输入(如 `"abc"`),均返回 `0`。 - **溢出风险**:若转换结果超出 `int` 范围(如 `2147483648`),行为未定义。 - **C风格字符串**:必须确保字符串以 `\0` 结尾,否则可能导致内存访问错误。 --- ### 5. 替代方案(推荐) - **C++的 `std::stoi`**: ```cpp #include <string> try { int num = std::stoi("1234"); // 支持异常处理 } catch (const std::invalid_argument& e) { // 处理无效输入 } catch (const std::out_of_range& e) { // 处理溢出 } ``` - **`strtol` 函数**: ```cpp char* end; long num = strtol("1234", &end, 10); // 可检测无效字符和溢出 ``` --- ### 总结 - **适用场景**:简单快速的字符串转整数,无需复杂错误处理。 - **缺点**:安全性低,建议在C++中优先使用 `std::stoi` 或 `std::stringstream`。
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 料

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值