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 type is left out of this party?
Specifically I am asking why there is not a version of atoi
with the safety features of strtod
?
Since strtol() can legitimately return 0, LONG_MAX, or LONG_MIN (LLONG_MAX or LLONG_MIN for strtoll()) on both success and failure, the calling program should set errno to 0 before the call, and then determine if an error occurred by checking whether errno has a nonzero value after the call. According to POSIX.
Returns. The strtol function returns the long integer representation of a string. The strtol function skips all white-space characters at the beginning of the string, converts the subsequent characters as part of the number, and then stops when it encounters the first character that isn't a number.
The strtol library function in C converts a string to a long integer. The function works by ignoring any whitespace at the beginning of the string, converting the next characters into a long integer, and stopping when it comes across the first non-integer character.
The atoi() function converts a character string to an integer value. The input string is a sequence of characters that can be interpreted as a numeric value of the specified return type. The function stops reading the input string at the first character that it cannot recognize as part of a number.
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.
Why is there no strtoi in stdlib.h?
No critical need.
In early C, there was not a standard signed integer 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()
. atoi()
fills the need for quick and dirty code to convert to an int
, but can lack error detection. On error, atoi()
incurs undefined behavior (UB). There also is no 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 str2subrange(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 str2i(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) str2subrange(s, endptr, base, INT_MIN, INT_MAX); #endif } short str2short(const char *s, char **endptr, int base) { return (short) str2subrange(s, endptr, base, SHRT_MIN, SHRT_MAX); } signed char str2schar(const char *s, char **endptr, int base) { return (signed char) str2subrange(s, endptr, base, SCHAR_MIN, SCHAR_MAX); } #include <stdint.h> int16_t str2int16(const char *s, char **endptr, int base) { return (int16_t) str2subrange(s, endptr, base, INT16_MIN, INT16_MAX); }
[Edit 2021]
To avoid conflicts with Future library directions, names changed from strto...()
to str2...()
.2
implying to
.
Function names that begin with
str
,mem
, orwcs
and a lowercase letter may be added to the declarations in the<string.h>
header. C17dr § 7.31.13 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With