首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux中atoi函数的实现 值得借鉴

atoi 函数是 C 语言标准库中的一个函数,用于将字符串转换为整数。其原型如下:

代码语言:txt
复制
int atoi(const char *str);

基础概念

atoi 函数的主要功能是将一个表示数字的字符串转换为一个整数。它会忽略字符串前面的空白字符(如空格、制表符等),直到遇到数字或正负号开始转换,直到遇到非数字字符为止。

实现原理

以下是一个简单的 atoi 函数的实现示例:

代码语言:txt
复制
#include <stdio.h>
#include <ctype.h>

int my_atoi(const char *str) {
    int result = 0;
    int sign = 1;
    int i = 0;

    // Skip leading whitespace
    while (isspace(str[i])) {
        i++;
    }

    // Handle sign
    if (str[i] == '-') {
        sign = -1;
        i++;
    } else if (str[i] == '+') {
        i++;
    }

    // Convert digits and ignore other characters
    while (isdigit(str[i])) {
        result = result * 10 + (str[i] - '0');
        i++;
    }

    return result * sign;
}

int main() {
    const char *test_str = "   -123abc";
    int num = my_atoi(test_str);
    printf("Converted number: %d\n", num);  // Output: -123
    return 0;
}

优势

  1. 简单易用atoi 函数的使用非常简单,只需传入一个字符串即可。
  2. 广泛支持:作为 C 语言标准库的一部分,几乎所有的 C 语言环境都支持 atoi 函数。

类型

atoi 函数返回的是一个 int 类型的整数。需要注意的是,atoi 函数在处理大数时可能会溢出,因为它没有检查转换后的数值是否在 int 类型的范围内。

应用场景

atoi 函数常用于从配置文件、用户输入或其他文本数据中提取整数值。例如:

  • 解析命令行参数
  • 读取配置文件中的整数值
  • 处理用户输入的数据

可能遇到的问题及解决方法

  1. 溢出问题:如果字符串表示的数字超出了 int 类型的范围,atoi 函数会返回一个不确定的值。可以使用 strtol 函数来代替 atoi,因为它可以处理更大的数值范围,并且可以检查溢出。
代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>

int main() {
    const char *test_str = "2147483648";  // 超出 int 范围
    char *endptr;
    long num = strtol(test_str, &endptr, 10);

    if (endptr == test_str || *endptr != '\0') {
        printf("Invalid input\n");
    } else if (num > INT_MAX || num < INT_MIN) {
        printf("Overflow or underflow\n");
    } else {
        printf("Converted number: %d\n", (int)num);
    }

    return 0;
}
  1. 非法字符:如果字符串中包含非数字字符,atoi 函数会停止转换并忽略后面的字符。可以使用 strtol 函数来获取更详细的错误信息。
代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>

int main() {
    const char *test_str = "123abc";
    char *endptr;
    long num = strtol(test_str, &endptr, 10);

    if (endptr == test_str || *endptr != '\0') {
        printf("Invalid input: %s\n", endptr);
    } else {
        printf("Converted number: %ld\n", num);
    }

    return 0;
}

参考链接

通过以上内容,你应该对 atoi 函数有了更深入的了解,并且知道如何处理可能遇到的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

你可能没有实现一个正确的atoi函数

前言 我们都知道,atoi函数用于将一个字符串转换成整数。atoi函数看起来似乎很容易实现,你甚至可以很快写出一个版本,但是是否符合要求呢?...123 * 10 + 4,即1234; 代码实现如下: int my_atoi(const char *str) { if(NULL == str) return 0;..."-1" "+1" " " "111111111111" "" "1aab" 是不是发现并不是想象中的那样?那么实现atoi到底需要注意什么呢?...实现atoi函数需要注意什么 你可能已经注意到了,实现atoi需要考虑下面这些场景: 输入正负号 开头有空格 转换后的数值超出int的表示范围 出错时返回0与正确转换0的区别 输入非数字 空字符串 现在来看...但这些都不是重点,重点是我们在考虑实现atoi函数的时候,需要考虑多种异常场景,这在平常实现其他功能接口的时候也是一样的。 思考 前面的代码有什么不足?你忽略了哪些场景?

2.4K20
  • linux中的sleep函数和delay函数

    对于做过单片机程序的朋友来说,delay是很常见的函数,通常就是while或者for循环,进行空指令的执行,由于单片机的晶振固定,一个机器周期的时间是固定的,执行多少个空指令, 就可以完成多少个机器周期时长的延时...其实在linux中的delay函数,道理是一样的,都是通过cpu执行空指令来达到延时的目的,但是对于操作系统这种多线程进行的方式来说,在需要延时的时候,可以通过将进程挂起的方式来实现延时。...这就是sleep函数。 sleep和delay的区别 最明显也最重要的区别就是,在执行delay的时候,是执行了空指令,虽说是空的,但是还是会占用硬件资源,cpu要进行运算。...两者对比可以看出,sleep执行的时候,节省系统资源,但是弊端是sleep的定时并没有那么准确,因为是通过进程切换来实现的,delay则是严格按照机器周期来计算,而且sleep不能适用于时间太短的延时,...当我们在设置一个芯片的各种引脚时序的时候,间隔较短且要求更准确,就需要delay。

    3.9K10

    axios源码中的10多个工具函数,值得一学~

    本文来自读者Ethan01投稿,写了axios源码中的工具函数~非常值得一学。...比如源码中的工具函数,就算是初级的前端开发也是能够看懂的。重要的是,要迈出这一步,阅读源码没什么的。...阅读本文,你将学到: 1、javascript、nodejs调试技巧及调试工具; 2、如何学习调试axios源码; 3、如何学习优秀开源项目的代码,应用到自己的项目; 4、axios源码中实用的工具函数...工具函数 今天的主角是`utils.js`[3]文件, 以下列出了文件中的工具函数: 3.1 isArray 判断数组 var toString = Object.prototype.toString;...4.总结 本文主要介绍了axios源码的调试过程,以及介绍了一些utils.js中的非常实用的工具函数;相信通过阅读源码,日积月累,并把这些代码或思想应用的自己项目中去,相信能够很好的提升自己的编码能力

    99850

    linux驱动ioctl函数,Linux中与驱动相关的ioctl函数

    ioctl是设备驱动程序中对设备的I/O通道进行管理的函数,所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如,在串口线上收发数据通过read/write操作,而串口的波特率、校验位、停止位通过...ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。...例如,我们可以在驱动程序中实现write的时候检查一下是否有特殊约定的数据流通过,如果有的话,那么后面就跟着控制命令(一般在socket编程中常常这样做)。...设备节点赋值,”/dev/video0″是真实的物理摄像头设备在linux中的表示 if (videodevice == NULL || *videodevice == 0) { videodevice...调用函数ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap))成功后可读取vd->capability各分量 video_capability是Video4linux支持的数据结构

    2.3K180

    Linux C中的open函数「建议收藏」

    大家好,又见面了,我是你们的朋友全栈君。 open函数属于Linux中系统IO,用于“打开”文件,代码打开一个文件意味着获得了这个文件的访问句柄。...); int fd = open(const char *pathname,int flags,mode_t mode); 1.句柄(file descriptor 简称fd) 首先每个文件都属于自己的句柄...close(fd)之后句柄就返回给系统,例如打开一个文件后fd是3,close之后再打开另外一个文件也还是3,但代表的文件不一样了。...使用open前需要先包含头文件 #include #include #include 3.参数1(pathname) 即将要打开的文件路径...open系统调用的那个进程的控制终端 O_TRUNC 如果文件已经存在泽删除文件中原有数据 O_APPEND 以追加的方式打开 主副可以配合使用,例如:O_RDWR|O_CREAT|O_TRUNC 5.

    3.3K10

    vim中函数跳转的功能实现

    介绍 函数跳转是要给IDE中非常重要也非常常用的功能,而原生的 Vim 并不提供这个功能,这个确定有点让人遗憾,按理说这么常用的功能应该是要提供的。...但是没有关系,有插件可以实现这样的功能更,借助像 ctags 这样的插件来实现。...安装完成后,可以在源代码的目录下执行以下命令来生成 tags 文件: ctags -R . 这个 tags 文件是一个包含所有函数和变量索引列表的文件,它使得在 Vim 中进行函数跳转成为可能。...使用跳转功能 在 Vim 中打开任意文件,并将光标移动到你想要跳转的变量或函数上。使用以下快捷键可以实现跳转: Ctrl + ]:快速跳转到函数或变量的定义处。 Ctrl + t:跳转回之前的位置。...配置 Vim:为了提高效率,可以在 .vimrc 文件中添加一些配置,比如设置 tags 文件的路径,或者定义快捷键等。

    46510

    Linux时序竞态问题(sleep函数的实现)

    比如说我们要使用alarm和pause函数来实现一个sleep的功能,那么由于alarm函数的实现过程并不是一个原子操作,那么随时可能被中断。...比如说alarm了1秒,在这个过程中,进程失去了CPU,然后当该进程再次获得CPU的时候可能这个时间已经大于1秒了,那么对于alarm来说就已经发出了SIGALRM信号。...此时往下继续调用pause函数的话,它会一直都收不到alarm发来的信号,所以导致进程的永久挂起。        为了解决这个问题,引用了sigsuspend函数。...进程在接收到UNBLOCK(mask之外)信号后,调用处理函数,然后还原信号集,sigsuspend返回,进程恢复执行。...下面通过使用alarm和sigsuspend函数来实现sleep函数,代码中有详细的注释来解释说明: #include #include #include <signal.h

    2.7K30

    Linux不同共享库中同名函数的处理

    场景引入: 在一个尚未成熟的行业中,一般行业标准是先于国家标准。这就导致了开发人员需要做很多兼容工作,再就是会用到很多其他厂商提供的库与头文件,面对不同版本的标准,一般会更新库与头文件。...那么此时如果要兼容新库和旧库要做怎样的操作呢? ①当两个C语言共享库之间有同名函数,链接时会报错么? ②如果不报错,调用的顺序是如何确定的呢? ③如果我想兼容两个库,该如何操作呢?...(别人的库无法更改函数名、C++可以使用命名空间) 方法是肯定有的,这次先测试①和②效果。 一、创建两个具有同名函数的共享库 1. 文件目录结构 ?...Makefile文件 TARGET=appTest ########CC=g++ #CC=arm-linux-gnueabi-gcc CFLAG=-g -Wall INCLUDE=-I.....一、小结 当两个共享库中有同名函数时,调用函数顺序取决于链接库顺序。

    3K10

    简单实现posix中规定的memcmp函数

    简介 memcmp函数的功能非常简单,传入两个指针s1和s2,以及要比较的字节大小n,比较这两块内存的值的差异(逐字节比较,把每个字节都翻译为unsigned char)。...当比较第i位时,如果相等,则返回0, 否则返回不相等的字节的差值(s1[i]-s2[i]). 实现 这个问题,本来是可以无脑的写c代码来逐字节比较的。...但是嘛,为了能够更高效的实现,咱们就手写汇编来做吧。 我们使用repe和cmpsb这两条指令来实现。...cmpsb指令则是对两个字节作比较的指令,在计算结束后,会设置相应的状态标志位。cmpsb指令涉及到的两个操作数分别存在rdi、rsi寄存器中。在操作结束后,如果这两个操作数的值相同,则会将ZF置位。...而输出nz到diff中,因此输出的是0. 如果某一字节不相同,那么diff=1。再在下面计算这两个字节到底相差了多少,然后就出结果了。

    66450

    JavaScript 函数式编程中的 curry 实现

    最近在学习javascript函数式编程,对其中大名鼎鼎的curry十分感兴趣,curry函数可以接受一个函数,我们暂且称之为原始函数,返回的也是一个函数,柯里化函数,这个返回的柯里化函数功能十分强大,...他在执行的过程中,不断的返回一个贮存了传入参数的函数,直到触发了原始函数执行的条件。...这个add需要两个参数,但是我们的curryAdd执行可以传入更少的参数,当传入的参数少于add需要的参数的时候,add函数并不会执行,curryAdd就会将这个参数记下来,并且返回另外一个函数,这个函数可以继续执行传入参数...curry函数要返回一个函数, 这个函数是要执行的,那么问题就是,我们要判断这个函数的执行是否激活了原始函数的执行,问题就出现在传入的参数上面。返回函数还是结果?...这的确是一个问题,我们先写返回结果的情况,当传入的参数等于原始函数需要的参数时,我们执行原始函数fn ?

    59840

    linux awk 函数定义变量赋值,Linux中的Awk定义、用法详解

    Awk是什么   Awk、sed与grep,俗称Linux下的三剑客,它们之前有很多相似点,但是同样也各有各的特色,相似的地方是它们都可以匹配文本,其中sed和awk还可以用于文本编辑,而grep则不具备这个功用...下面的例子简单地打印文件的每一行,这里不带任何参数的print语句打印的是整个记录,类似’print $0‘:   除了 { action },还可以在脚本中定义自定义的函数,函数定义格式如下所示:   ...函数的参数列表用逗号分隔,参数默认是局部变量,无法在函数之外访问,而在函数中定义的变量为全局变量,可以在函数之外访问,如:   Awk脚本中的语句使用空行或者分号分隔,使用分号可以放在同一行,不过有时候会影响可读性...,这样我们可以用表达式$n ~ /ere/:   有时候我们只想显示特定和行,例如显示第一行:   正则表达式( )   正则表达式的内容介绍起来太麻烦,还是推荐同学阅读现有的文章(如Linux/Unix...利用rand()函数我们也可以生成1到n的整数:   字符串函数   awk中包含大多数常见的字符串操作函数。

    9.6K50

    利用函数类型实现封装中的回调

    当进行业务逻辑开发的时候,经常要进行封装,封装成独立的类文件,在类文件的属性中预留出函数类型的API 在调用该类文件中某些方法的时候,也根据业务需要调用类属性中的函数, 在主业务中可以传递特定的函数注册到属性中...package main import "log" func main() { c := NewConn(callback, callback2) c.Start() } //在当前模块定义的回调函数...,回调类主模块中的函数 package main type Connection struct{ handleFunc func() handleFunc2 func(name string...)string } //把被回调函数注册进了封装类的属性中 func NewConn(callback func(),callback2 func(name string)string) *Connection...Connection{ handleFunc: callback, handleFunc2: callback2, } return c } //在进行某些业务时也把回调函数执行了

    2.4K10
    领券