Validate max integer in scanf

前端 未结 4 1716
独厮守ぢ
独厮守ぢ 2020-12-15 11:20

I want to read a int from stdin but I want to validate if the user exceeds the int max value. How can I do it?

int n;
scanf(\"%d\", &n);
<
相关标签:
4条回答
  • 2020-12-15 12:01

    Another way is to set max digits to parse.

    For example:

      int n;
      scanf("%5d", &n); // read at most 5 digits
      printf("%i\n", n);
    
    0 讨论(0)
  • 2020-12-15 12:04

    The only way to convert a string representation of a number to the actual value and to watch for overflow is to use functions from strto.. group. In your case you need to read in a string representation of the number and then convert it using strtol function.

    Beware of responses that suggest using atoi or sscanf to perform the final conversion. None of these functions protect from overflow.

    0 讨论(0)
  • 2020-12-15 12:07

    Two methods come to mind.

    The first is useful if you know the input is integer-like only input, but suffers from "slightly" exceeding integer range:

    long x;
    if (1 != scanf("%ld", &x))
             error "not a number or other i/o error"
    else
    if (x < -MAXINT ||  x > MAXINT)
            error "exceeds integer range"
    else    printf "it is an integer";
    

    This has a lot of dependency on the compiler and platform. Note that the C language guarantees only that long is greater than or equal to the size of int. If this is run on a platform where long and int are the same size, it is a useless approach.

    The second approach is to read the input as a string and parse straightforwardly:

    char buf [1000];
    if (1 != scanf ("%1000s", buf))
            error "i/o error";
    size_t len = strspn (buf, "0123456789+-");
    if (len != strlen (buf))
            error "contains invalid characters";
    long  number = 0;
    int   sign = 1;
    for (char *bp = buf;  *bp;  ++bp)
    {
              if (*bp == '-')
              {
                   sign = -sign;
                   continue;
              }
              if (*bp == '+')
                   continue;
              number = number * 10  +  *bp - '0';
              if (number > MAXINT)
                   error "number too large";
    }
    if (sign < 0)
             number = -number;
    

    This code has several weaknesses: it depends on long being larger than int; it allows plus and minus to appear anywhere in the string. It could be easily extended to allow other than base ten numbers.

    A possible third approach might be to input a string check the character set and use a double conversion to range check.

    0 讨论(0)
  • 2020-12-15 12:07

    Read it into a string and check the length, then call either atol() or sscanf() on the string to convert it into a int.

    0 讨论(0)
提交回复
热议问题