1

I want to convert a string (guaranteed to consist only of digits) to a 32-bit int. I know of strtol and strtoimax, but these seem to return 64-bit ints.

This is how I'm currently doing it:

#include <errno.h>
#include <inttypes.h>

typedef int32_t Int32;

Int32 strToIntValue(char* str) {
    char* end;
    errno = 0;
    int ret = strtoimax(str, &end, 10);

    if (errno==ERANGE) {
        printf("range error!\n");
        return 0;
    }
    else {
        return (Int32)ret;
    }
}
Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • 3
    Can you just add something like: `else if (ret < INT_MIN || ret > INT_MAX) { … error code`? (Or, more specifically, `INT32_MIN` and `INT32_MAX` if you have ``.) – Adrian Mole Dec 26 '19 at 08:41
  • 1
    If you’re sure the string just has digits, error checking is not essential and you can use `atoi` – Jim Danner Dec 26 '19 at 08:43
  • 2
    @JimDanner But what will `atoi` do if the number is out-of-range? – Adrian Mole Dec 26 '19 at 08:49
  • 3
    Re "*`typedef int32_t Int32;`*", Why add this level of obfuscation??? – ikegami Dec 26 '19 at 08:56
  • 1
    @AdrianMole Apparently in such cases the behavior is undefined, https://stackoverflow.com/a/8871717/7840347 – Jim Danner Dec 26 '19 at 08:57
  • @JimDanner And that's a very good reason to **NEVER** use `atoi()` - you can not tell if the returned value is an error or not. – Andrew Henle Dec 26 '19 at 10:24
  • Please tell us more about the allowed range. – the busybee Dec 26 '19 at 10:29
  • @AdrianMole [Why shouldn't I use atoi()?](https://stackoverflow.com/q/17710018/995714) – phuclv Dec 26 '19 at 10:33
  • @phuclv I didn't suggest using `atoi`! I would use the OP's posted code with the added checks stated in my first comment. – Adrian Mole Dec 26 '19 at 10:36
  • @AndrewHenle It is certainly a bad idea to use `atoi` with random inputs, or user inputs etc. Only use it if you know exactly what format the input has. I can't determine what the OP knows about the inputs - for example, the input is "guaranteed to consist only of digits", so perhaps there are other known properties. – Jim Danner Dec 27 '19 at 12:21

1 Answers1

0

The standard C library does not have a strtoint32().

I want to convert a string ... to a 32-bit int.
I know of strtol and strtoimax, but these seem to return 64-bit ints.

There is long strtol() that certainly meets OP's needs. It forms an integer at least 32-bits. Use it and additional tests if needed.

#include <ctype.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>

// really no need for this:
// typedef int32_t Int32;

// Int32 strToIntValue(char* str) {
int32_t strToIntValue(const char* str) {
    char* end;
    errno = 0;
    long num = strtol(str, &end, 10);
    if (num == end) {
        printf("No conversion error!\n");
        return 0;
    }

    #if LONG_MAX > INT32_MAX
    if (num > INT32_MAX) {
      num = INT32_MAX;
      errno = ERANGE;
    }
    #endif 

    #if LONG_MIN < INT32_MIN
    if (num < INT32_MIN) {
      num = INT32_MIN;
      errno = ERANGE;
    }
    #endif 

    if (errno==ERANGE) {
      printf("range error!\n");
      return 0;
    }

    // Maybe check for trailing non-white space?
    while (isspace((unsigned char) *end) {
      end++;
    }
    if (*end) {
      printf("Trailing junk!\n");
      return 0;
    }

    // else {
    return (int32_t) num;
    //}
}

Consider printing error output to stderr rather than stdout.

        // printf("range error!\n");
        fprintf(stderr, "range error!\n");

See Why is there no strtoi in stdlib.h? for more ideas.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256