【问题标题】:atoi() — string to intatoi() — 字符串到 int
【发布时间】:2010-12-02 02:15:10
【问题描述】:

我读到atoi() 已被弃用,它相当于:

(int)strtol(token_start, (char **)NULL, 10);

这是否意味着我应该使用上面的而不是 atoi(chr) 或者只是说它们是等价的?

【问题讨论】:

  • atoi 的问题:assert( atoi("0") != atoi(!blah") )
  • atoi 很差,因为它几乎没有明确定义的错误检测,但即使使用strtol,正确检测(和分类)错误也非常困难,而且这里没有一个真正的答案解决这个问题。请参阅this question 的答案以获得一些指导。

标签: c


【解决方案1】:

这意味着在某个时间点 atoi 将不再可用。所以现在就开始修改你的代码

【讨论】:

  • 我知道那部分,但想知道 atoi 的实现是否只是调用了上面的代码。
  • 这是不正确的,需要引用。当前的 C 标准中没有任何内容表明 atoi 已被弃用。这是做出这个答案的 6 年后,C11 是现行标准。
【解决方案2】:

在 Apple 的 Mac OS X Manual Page for atoi(3)(以及 BSD 手册页)上确实表明 atoi 已被弃用。

atoi() 函数已被 strtol() 弃用,不应再使用 在新代码中使用。

出于这个原因,我会使用 strtol() 等效项,但我怀疑您不必担心 atoi() 被删除。

来自http://www.codecogs.com/library/computing/c/stdlib.h/atoi.php 实施说明

* The atoi function is not thread-safe and also not async-cancel safe.
* The atoi function has been deprecated by strtol and should not be used in new code.

【讨论】:

  • 不只取决于atoi的内部实现是否是线程安全的吗?如果不是,那么是什么使它在外部不是线程安全的?
  • 他们一定非常努力地使它不是线程安全的。天真的实现肯定是。
  • 需要注意的是,并非所有编译器都支持 sto* 函数,例如 Android NDK。有关更多信息,请参阅此问题:stackoverflow.com/questions/15499070/…
  • atoi 的 glibc 手册页说:“atoi()、atol() 和 atoll() 函数是线程安全的,但有异常。这些函数可以在多线程应用程序中安全使用,只要在执行期间不会调用 setlocale(3) 来更改语言环境。"
  • 这个答案,或者更确切地说是来源,是不正确/不相关的。某个函数是否是线程安全的确实取决于编译器的实现。我不明白为什么不会。 atoi 在这方面与 strol 函数没有什么不同。更重要的是,atoi 肯定不会被弃用。在 C11 标准中,它不是在 2009 年,现在也不是。
【解决方案3】:

description of atoi()strtol() 的相似点/不同点有一个非常重要的点

> ... The call atoi(str) shall be equivalent to:
> (int) strtol(str, (char **)NULL, 10)
> except that the handling of errors may differ.

试试这个好玩:

const char *buf = "forty two";
int t1 = atoi(buf);             /* detect errors? */
int t2 = strtol(buf, NULL, 10); /* detect errors? */

【讨论】:

  • 我已经在我的编译器 (GCC) 上尝试了你的代码,并且都给了我0,所以我看不出有什么区别:|
  • 嗯,我的错!谢谢@SasQ。我以为strtol 必须将errno 设置为错误,但在我上面的测试代码的特定情况下,它没有。
  • @pmg 您的测试代码似乎根本没有检查errno
【解决方案4】:

不,你不应该使用上面的来代替atoi

您实际上应该检查strtol 提供的错误信息:

i = atoi(s);

应该替换为

char* stopped;
i = (int)strtol(s, &stopped, 10);
if (*stopped) { /* handle error */ }

【讨论】:

    【解决方案5】:

    atoi 未被弃用,您的来源不正确。当前的 C 标准 ISO 9899:2011 中没有任何内容表明这一点(例如参见第 6.11 章未来的语言方向),早期标准中也没有任何内容。

    根据C标准,atoi相当于strtol如下,C11 7.22.1.2:

    atoi、atol 和 atoll 函数将 nptr 指向的字符串为 int、long int 和 long long int 分别表示。

    除了错误的行为,它们等价于

    atoi: (int)strtol(nptr, (char **)NULL, 10)

    atol: strtol(nptr, (char **)NULL, 10)

    atoll: strtoll(nptr, (char **)NULL, 10)

    strtol 是首选,因为 atoi 在错误时调用未定义的行为。见 7.22.1 “如果结果的值不能表示,则 行为未定义。”

    【讨论】:

    • (是的,我知道这个问题非常古老,但接受的答案不正确,必须澄清)
    • “如果结果的值无法表示,则行为未定义”。当然,这会使该功能完全无法使用,并且有充分的理由认为该功能已被有效弃用。
    • @WilliamPursell 确实如此。再给 C 标准委员会几十年时间,他们可能会意识到。例如,他们花了 22 年时间才删除 gets。效率和主动性的缩影。将此与 MISRA-C 安全子集标准进行比较,该标准早在 1998 年就禁止所有使用 ato* 函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多