我看到atoi()
已经被弃用了,它的等价函数是:
(int)strtol(token_start, (char **)NULL, 10);
这是否意味着我应该使用上述方法而不是atoi(chr)
,还是说它只是在说它们是等效的?
我看到atoi()
已经被弃用了,它的等价函数是:
(int)strtol(token_start, (char **)NULL, 10);
这是否意味着我应该使用上述方法而不是atoi(chr)
,还是说它只是在说它们是等效的?
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:“如果无法表示结果的值,则行为是未定义的。”
gets
。这是效率和主动性的典范。与此相比,MISRA-C安全子集标准在1998年就禁止了所有ato*函数的使用。 - Lundin在Apple的Mac OS X手册页(以及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
函数是否是线程安全的,仅取决于它的内部实现吗?如果不是,那是什么导致了它在外部不是线程安全的? - SasQstrtol()
的相似性和差异有一个非常重要的点。>...调用atoi(str)等同于:
>(int) strtol(str, (char **)NULL, 10)
>除了错误处理可能不同。
const char *buf = "forty two";
int t1 = atoi(buf); /* detect errors? */
int t2 = strtol(buf, NULL, 10); /* detect errors? */
0
,所以我没有看到任何区别 :| - SasQstrtol
在出错时必须设置 errno
,但在我上面的测试代码的特定情况下,它并没有这样做。 - pmgerrno
。 - Dan Bechardatoi
。strtol
提供的错误信息:i = atoi(s);
应该被替换为
char* stopped;
i = (int)strtol(s, &stopped, 10);
if (*stopped) { /* handle error */ }
atoi()
在之前或当前的C标准中都没有被弃用。
atoi(nptr)
与(int)strtol(nptr, (char **)NULL, 10);
相似,但在出错时有所不同。
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
// To Do: refine error codes, perhaps as enum?
#define ATOI_BAD_ARG 1
#define ATOI_NO_CONVERSION 2
#define ATOI_RANGE 3
#define ATOI_EXTRA 4
int atoi_alt(const char *nptr, int *errorptr);
// Side effect: errno is assigned.
int atoi_alt(const char *nptr, int *errorptr) {
int dummy;
if (errorptr == NULL) {
errorptr = &dummy;
}
if (nptr == NULL) {
*errorptr = ATOI_BAD_ARG;
return 0;
}
errno = 0;
char *end;
long lvalue = strtol(nptr, &end, 10);
if (nptr == end) {
*errorptr = ATOI_NO_CONVERSION;
return 0;
}
#if LONG_MIN == INT_MIN && LONG_MAX == INT_MAX
if (errno == ERANGE) {
*errorptr = ATOI_RANGE;
return (int) lvalue;
}
#else
if (errno == ERANGE || lvalue < INT_MIN || lvalue > INT_MAX) {
errno = ERANGE;
*errorptr = ATOI_RANGE;
return (lvalue < 0) ? INT_MIN : INT_MAX;
}
#endif
while (isspace(((unsigned char* ) end)[0])) {
end++;
}
*errorptr = *end ? ATOI_EXTRA : 0;
return (int) lvalue;
}
errno
将错误信息传递回调用者 - 这是我的设计选择。很容易修改代码以做出其他选择。这意味着在某个时间点上,atoi将不再可用。所以现在开始改变你的代码吧。
atoi()
的问题是:assert( atoi("0") != atoi("!blah") )
。 - sbiatoi
很差,因为它几乎没有定义良好的错误检测,但即使使用strtol
,正确地检测(和分类)错误也令人惊讶地困难,并且这里没有任何答案真正解决了这个问题。请参阅此问题中的答案以获得一些指导。 - Steve Summit