简体   繁体   中英

Why is there no strtoi in stdlib.h?

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 ?

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 or cause 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 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);
}

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;

It's callatoi . See also Wikipedia for details, including its successor strol .

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 technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM