Why is there no strtoi in stdlib.h?

后端 未结 6 1981
深忆病人
深忆病人 2020-11-27 16:34

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

相关标签:
6条回答
  • 2020-11-27 16:46

    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.

    0 讨论(0)
  • 2020-11-27 16:46

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

    0 讨论(0)
  • 2020-11-27 16:47

    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);
    }
    
    0 讨论(0)
  • 2020-11-27 16:53

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

    0 讨论(0)
  • 2020-11-27 16:55

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

    0 讨论(0)
  • 2020-11-27 16:58

    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;
    
    0 讨论(0)
提交回复
热议问题