Why is there no strtoi in stdlib.h?

CLibc

C Problem Overview


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?

C Solutions


Solution 1 - C

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.

Solution 2 - C

> 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.

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, or wcs and a lowercase letter may be added to the declarations in the <string.h> header. C17dr § 7.31.13 1

Solution 3 - C

The integer isn't left out of the party: there is strtol, which converts a string to a long, which is an integer type.

Solution 4 - C

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;

Solution 5 - C

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

Solution 6 - C

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). :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEliView Question on Stackoverflow
Solution 1 - CWizView Answer on Stackoverflow
Solution 2 - Cchux - Reinstate MonicaView Answer on Stackoverflow
Solution 3 - CJames McNellisView Answer on Stackoverflow
Solution 4 - CMarc K.View Answer on Stackoverflow
Solution 5 - CmtrwView Answer on Stackoverflow
Solution 6 - CsarnoldView Answer on Stackoverflow