Reputation: 19648
I read that atoi()
is deprecated and that it is equivalent to:
(int)strtol(token_start, (char **)NULL, 10);
Does that mean I should use the above instead of atoi(chr)
or is it just saying they are equivalent?
Upvotes: 12
Views: 30088
Reputation: 154572
atoi()
is not deprecated by the prior or the current C standard.
atoi(nptr)
is like (int)strtol(nptr, (char **)NULL, 10);
except on errors.
Now, how to detect and resolve errors?
Consider using a helper function: int atoi_alt(const char *nptr, int *errorptr);
Possible errors and candidate resolutions:
Out-of-range: conversion leads to a value outside the [INT_MIN
... INT_MAX
] range like atoi_alt("1234567890123456789012345678901234567890", ...);
. Return either INT_MIN
or INT_MAX
(matching the sign of the original conversion) and a non-zero error.
No conversion: conversion fails as the string begins with non-numeric, non-white-space text like atoi_alt("!@#$1234", ...);
. Return 0 and a non-zero error.
No conversion: conversion fails as the string is empty like atoi_alt("", ...);
. Return 0 and a non-zero error.
Non-numeric trailing text: Initial conversion works, yet extra, non-white-space, text exists like atoi_alt("1234!@#$", ...);
. Return converted value and a non-zero error. Note that with strtol()
, this is not an error.
White-space trailing text: Initial conversion works, white-space follows like atoi_alt("1234\n", ...);
. Return converted value and a zero error. Note that with strtol()
, this is not an error.
White-space begins text: Ignore leading white-space and convert as above. Note that this is consistent with atoi()
and strtol()
and itself is not an error.
String not supplied: As nptr == NULL
, return 0 and a non-zero error. Note that with strtol()
, this is undefined behavior (UB).
Error address not supplied: Perform as above, but do not set an error.
Sample alternative code:
#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;
}
Code purposely does not carry the error information back to the caller via errno
- my design choice. Easy enough to amend code to do otherwise.
Upvotes: 0
Reputation: 83729
It does say on Apple's Mac OS X Manual Page for atoi(3) (and in the BSD man pages too) that atoi
has been deprecated.
The atoi() function has been deprecated by strtol() and should not be used in new code.
I would use the strtol()
equivalent just for that reason, but i doubt you have to worry about atoi()
being removed.
from http://www.codecogs.com/library/computing/c/stdlib.h/atoi.php
Implementation Notes
* 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.
Upvotes: 8
Reputation: 215330
atoi
is not deprecated, your source is incorrect. Nothing in the current C standard ISO 9899:2011 indicates this (see for example chapter 6.11 future language directions), nor anything in earlier standards.
As per the C standard, atoi is equivalent to strtol as follows, C11 7.22.1.2:
The atoi, atol, and atoll functions convert the initial portion of the string pointed to by nptr to int, long int, and long long int representation, respectively.
Except for the behavior on error, they are equivalent to
atoi: (int)strtol(nptr, (char **)NULL, 10)
atol: strtol(nptr, (char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)
strtol is preferred, as atoi invokes undefined behavior upon error. See 7.22.1 "If the value of the result cannot be represented, the behavior is undefined."
Upvotes: 23
Reputation: 283921
No, you shouldn't use the above instead of atoi
.
You should actually check the error information that strtol
makes available:
i = atoi(s);
should be replaced by
char* stopped;
i = (int)strtol(s, &stopped, 10);
if (*stopped) { /* handle error */ }
Upvotes: 3
Reputation: 108986
The description of atoi()
has one very important point in relation to the similarities/differences to strtol()
> ... The call atoi(str) shall be equivalent to:
> (int) strtol(str, (char **)NULL, 10)
> except that the handling of errors may differ.
Try this for fun:
const char *buf = "forty two";
int t1 = atoi(buf); /* detect errors? */
int t2 = strtol(buf, NULL, 10); /* detect errors? */
Upvotes: 4
Reputation: 15935
it means that at one point in time atoi will not be available anymore. So start changing your code now
Upvotes: -3