gcc 4.4.4 c89

哪种方法更好地将字符串转换为整数值.

我已经try 了两种不同的方法Atoi和Sscanf.两者都像预期的那样工作.

char digits[3] = "34";
int device_num = 0;

if(sscanf(digits, "%d", &device_num) == EOF) {
    fprintf(stderr, "WARNING: Incorrect value for device\n");
    return FALSE;
}

或使用Atoi

device_num = atoi(digits);

我在想sscanf会更好,因为您可以判断错误.然而,Atoi没有做任何判断.

推荐答案

您有3个 Select :

  1. atoi

如果您在性能关键型代码中使用它,这可能是最快的,但是它不会报告错误.如果字符串不是以整数开头,则返回0.如果字符串在整数后包含垃圾,它将转换初始部分并忽略睡觉.如果数字太大而无法容纳int,则行为未指定.

  1. sscanf

一些错误报告,并且对于存储什么类型(char/short/int/long/long long/size_t/ptrdiff_t/intmax_t的签名/未签名版本)有很大的灵活性.

返回值是成功的转换数,因此如果字符串不是以整数开头,则扫描"%d"将返回0.您可以使用"%d%n"来存储在另一个变量中读取的整数之后的第一个字符的索引,从而判断整个字符串是否已转换,或者之后是否有垃圾.然而,像atoi个一样,整数溢出的行为是未指定的.

  1. strtol和家庭

强大的错误报告功能,前提是在通话前将errno设置为0.返回值在溢出时指定,并将设置为errno.您可以 Select 2到36之间的任何数字基数,或者指定0作为基数,以分别将前导0x0自动解释为十六进制和八进制.要转换为的类型 Select 是long/long long/intmax_t的有符号/无符号版本.

如果您需要较小的类型,您可以始终将结果存储在一个临时的longunsigned long变量中,并自己判断是否有溢出.

由于这些函数接受指向指针参数的指针,因此您还可以免费获得指向转换后的整数后面的第一个字符的指针,因此您可以判断整个字符串是否为整数,或者在需要时解析字符串中的后续数据.


就我个人而言,我会推荐strtol个家庭用于most个目的.如果你正在做一些快速和肮脏的事情,Atoi可能会满足你的需求.

顺便说一句,有时我发现我需要解析一些不应该接受前导空格、符号等的数字.在这种情况下,你可以很容易地实现自己的for循环,例如.,

for (x=0; (unsigned)*s-'0'<10; s++) 
    x=10*x+(*s-'0');

或者你可以使用(为了稳健性):

if (isdigit(*s))
    x=strtol(s, &s, 10);
else /* error */ 

C++相关问答推荐

当包含头文件时,gcc会发出隐式函数声明警告

为什么在C中设置文件的位置并写入文件,填充空字符?

在使用GTK 4 Columnview列表模型时,如何为多列添加排序函数.C编码,Linux/GNOME环境

DPDK-DumpCap不捕获端口上的传入数据包

C编译器是否遵循restrict的正式定义?

测量ARM MCU中断延迟的问题

在C语言中,在数学运算过程中,为什么浮点数在变量中的行为不同

是否可以使用指针算法在不对齐的情况下在 struct 中相同类型的字段的连续序列之间移动?

我怎么才能用GCC编译一个c库,让它包含另一个库呢?

S在本文中的价值观到底出了什么问题?

搜索使用int代替time_t的用法

从整型转换为浮点型可能会改变其值.

Linux/C:带有子进程的进程在添加waitid后都挂起

如何打印循环调度问题的时间表

gdb - 你能找到持有内部 glibc 锁的线程吗?

根据输入/输出将 C 编译过程分为预处理、编译、汇编和链接步骤

无法在线程内用 C 打印?

如何使用 raylib 显示数组中的图像

Zig 中 C 的system函数的惯用替代方案

inline 关键字导致 Clion 中的链接器错误