首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >atoi vs atol vs strtol vs strtoul vs sscanf

atoi vs atol vs strtol vs strtoul vs sscanf
EN

Stack Overflow用户
提问于 2014-04-04 14:30:23
回答 2查看 37.5K关注 0票数 32

我试图从被解析的命令行中找出哪个函数最适合于将十进制、十六进制或八进制数字转换为最佳的int --事先不知道输入。

然后,目标是使用单个函数来识别不同类型的输入,并将其赋值为整数(int)值,然后可以这样使用:

代码语言:javascript
运行
复制
./a.out 23 0xC4 070

能打印

代码语言:javascript
运行
复制
23
196 /*hexadecimal*/
56  /*octal*/

我看到的唯一问题是解析,以查找十进制整数和八进制之间的差异。

附带的问题是,对于将字符串转换为整数以供使用,这是否稳定?

EN

回答 2

Stack Overflow用户

发布于 2014-04-04 14:48:10

哪个函数最好将十进制、十六进制或八进制数字转换为int (?)

要将这样的文本转换为int,如果需要的话,建议在转换为int时使用附加测试的long strtol(const char *nptr, char **endptr, int base);

使用0作为base评估早期字符在转向转换为基数10,16或8。

@Mike Holt

代码语言:javascript
运行
复制
Convert text per:
Step 1: Optional whitespaces like `' '`, tab, `'\n'`, ... .
Step 2: Optional sign: `'-'` or `'+'`.
Step 3:
  0x or 0X followed by hex digits--> hexadecimal  
  0 --> octal  
  else --> decimal  

样本代码

代码语言:javascript
运行
复制
#include <errno.h>
#include <limits.h>
#include <stdlib.h>

int mystrtoi(const char *str) {
  char *endptr;
  errno = 0;
  //                                   v--- determine conversion base
  long long_var = strtol(str, &endptr, 0);
  //   out of range   , extra junk at end,  no conversion at all   
  if (errno == ERANGE || *endptr != '\0' || str == endptr) {
    Handle_Error();
  }

  // Needed when `int` and `long` have different ranges
  #if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
  if (long_var < INT_MIN || long_var > INT_MAX) {
    errno = ERANGE;
    Handle_Error();
  }
  #endif

  return (int) long_var;
}

atoi vs atol vs strtol vs strtoul vs sscanf .int

atoi()

非常简单。

Pro:转换为int

支持:在C标准库中。

快。

对于超出范围的错误,未定义的行为。@chqrlie

既不处理十六进制也不处理八进制。

atol()

赞成:简单。

支持:在C标准库中。

快。

Con:转换为long,而不是可能大小不同的int

对于超出范围的错误,未定义的行为。

既不处理十六进制也不处理八进制。

strtol()

赞成:简单。

支持:在C标准库中。

支持:很好的错误处理。

快。

Pro:能处理二进制文件。(基数2至36)

Con:转换为long,而不是可能大小不同的int

strtoul()

赞成:简单。

支持:在C标准库中。

支持:很好的错误处理。

快。

Pro:能处理二进制文件。

-不抱怨负数

Con:转换为unsigned long,而不是可能大小不同的int

sscanf(..., "%i", ...)

支持:在C标准库中。

Pro:转换为int

-道路的复杂性

潜在的慢点。

Con: OK错误处理(溢出未定义)。

所有这些都受到/受益于locale设置。§7.22.1.4 6除"C“区域外,还可接受附加的特定地区主题序列形式。

额外贷项:

@Jonathan Leffler:针对ERANGEerrno测试,atoi()十进制测试,讨论errno多线程关注点.

@Marian速度问题。

@凯文图书馆包容性。

要转换shortsigned char等,请考虑strto_subrange()

票数 39
EN

Stack Overflow用户

发布于 2014-04-04 14:47:59

如果您关心错误条件,那么只需要考虑strtol()strtoul() (或者<stdlib.h>中的strtoll()strtoull(),或者<inttypes.h>中的strtoimax()strtoumax() )。如果您不关心溢出的错误条件,则可以使用它们中的任何一个。atoi()atol()sscanf()都不能控制值是否溢出。此外,atoi()atol()都不支持十六进制或八进制输入(因此实际上不能使用它们来满足您的需求)。

请注意,调用strtoX()函数并不完全简单。在调用它们之前,您必须将errno设置为0,并传递一个指针以获得结束位置,并仔细分析以了解发生了什么。请记住,来自这些函数的所有可能的返回值都是有效的输出,但其中一些可能也表示无效的输入-- errno和end指针帮助您区分所有输入。

如果需要在使用strtoll()读取值之后转换为strtoll(),则可以根据<limits.h> for intINT_MININT_MAX中定义的范围检查返回值的范围(存储在long long中)。

有关详细信息,请参阅我在以下网站的回答:strtol()

请注意,这些函数都没有告诉您使用了哪种转换。你需要自己分析一下绳子。奇怪的注意:您是否知道C源中没有小数点0;当您编写0时,您正在写入一个八进制常数(因为它的第一个数字是0)。这件小事没有任何实际后果。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22865622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档