I have grown accustomed to strtod and variants.
I am wondering why there is no strtoi shipped with stdlib.h.
Why is it that the integer is left out of this part
strtol() converts a string to an integer, a long integer but an integer nevertheless. There is atoi() but it should be avoided in most cases due to the fact that it lacks a mechanism for error reporting from invalid input.
It's call atoi. See also Wikipedia for details, including its successor strol.
Why is there no strtoi in stdlib.h?
No critical need.
In early C, there was not a standard signed type wider than long and all narrower conversions, like int, could be made from strtol() - as done below.
IMO, these and their unsigned counterparts are now missing C functions and a design shortcoming in the current standard C library (C17/18).
On many systems, long and int have the same range and so there is a reduced need for a separate strtoi(). Also the atoi() fills the need for quick and dirty code, but can lack error detection. There also is not a strto_short() nor strto_signchar(), etc.
It is fairly easy to create a substitute strtoi(). Simplifications exist.
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
static long strto_subrange(const char *s, char **endptr, int base,
long min, long max) {
long y = strtol(s, endptr, base);
if (y > max) {
errno = ERANGE;
return max;
}
if (y < min) {
errno = ERANGE;
return min;
}
return y;
}
// OP's goal
int strtoi(const char *s, char **endptr, int base) {
#if INT_MAX == LONG_MAX && INT_MIN == LONG_MIN
return (int) strtol(s, endptr, base);
#else
return (int) strto_subrange(s, endptr, base, INT_MIN, INT_MAX);
#endif
}
short strtoshort(const char *s, char **endptr, int base) {
return (short) strto_subrange(s, endptr, base, SHRT_MIN, SHRT_MAX);
}
signed char strtoschar(const char *s, char **endptr, int base) {
return (signed char) strto_subrange(s, endptr, base, SCHAR_MIN, SCHAR_MAX);
}
#include <stdint.h>
int16_t strtoint16(const char *s, char **endptr, int base) {
return (int16_t) strto_subrange(s, endptr, base, INT16_MIN, INT16_MAX);
}
Don't overlook the SEE ALSO section of your manpages :)
SEE ALSO atof(3), atoi(3), atol(3), strtol(3), strtoul(3)
You're looking for atoi(3). :)
The integer isn't left out of the party: there is strtol, which converts a string to a long, which is an integer type.
This is what I have been using.
long long_val;
int int_value;
errno = 0;
long_val = strtol (theString, NULL, 10);
if (errno)
handle_error;
if ((long) someIntMin > long_val || long_val > (long) someIntMax)
handle_invalid;
int_value = (int) long_val;