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?
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."
gets. The very epitome of efficiency and initiative. Compare this with the MISRA-C safe subset standard, which banned all use of the ato* functions as early as 1998.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. atoi whether it's thread-safe or not? If not, then what makes it not thread-safe on the outside?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? */ 0, so I don't see any difference :|strtol had to set errno on error, but in the specific case of my test code above, it doesn't.errno at all.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.
it means that at one point in time atoi will not be available anymore. So start changing your code now
atoi:assert( atoi("0") != atoi(!blah") )atoiis poor because it does almost no well-defined error detection, but even when usingstrtol, properly detecting (and classifying) errors is surprisingly difficult, and none of the answers here really addresses that. See the answers at this question for some guidance.