1

I have to get a int in input, to validate it i wrote:

 do {
    scanf("%d", &myInt);
    if (myInt >= 2147483648 || myInt <= -2147483648)
        printf("I need an integer between -2147483647 and 2147483647: ");
} while (myInt >= 2147483648 || myInt <= -2147483648);

But if I insert a char, it starts with an infinite loop, but I would simply validate the int value.

LihO
  • 41,190
  • 11
  • 99
  • 167
M4rk
  • 2,172
  • 5
  • 36
  • 70
  • If those numbers are INT_MAX, and INT_MIN, wouldn't that if statement never be true? – Charlie Burns Oct 18 '13 at 18:53
  • @CharlieBurns I would think so. Unless those are hard-coded for 32bit limits on a 64bit `int` architecture (i.e. the OP is using 64bit `int` but wants 32bit limits), it does seem somewhat pointless. – WhozCraig Oct 18 '13 at 18:54
  • @WhozCraig, I was thinking < and > . He has <= and >= so it would be true for INT_MIN and INT_MAX. Nonetheless, I doubt that is what he was thinking. – Charlie Burns Oct 18 '13 at 18:56

2 Answers2

2

Use the return value of scanf to achieve this:

int myInt;
while (scanf("%d", &myInt) != 1) {
    // scanf failed to extract int from the standard input
}
// TODO: integer successfully retrieved ...
LihO
  • 41,190
  • 11
  • 99
  • 167
  • Wouldn't it be the opposite? `while (scanf("%d", &myInt) != 1) { //TODO: scanf failed to retrieve integer ... } ` – fvdalcin Oct 18 '13 at 18:54
  • Only problem with this is that if the user enters something like `12w3`, the `12` will be converted and assigned to `myInt` and `scanf` will return 1, leaving the `w3` in the input stream to foul up the next read. – John Bode Oct 18 '13 at 19:46
0

This is why I usually advise against using scanf for interactive input; for the amount of work required to make it really bulletproof, you might as well use fgets() and use strtod or strtol to convert to numeric types.

char inbuf[MAX_INPUT_LENGTH];
...
if ( fgets( inbuf, sizeof inbuf, stdin ))
{
  char *newline = strchr( inbuf, '\n' );
  if ( !newline )
  {
    /**
     * no newline means that the input is too large for the
     * input buffer; discard what we've read so far, and
     * read and discard anything that's left until we see
     * the newline character
     */
    while ( !newline )
      if ( fgets( inbuf, sizeof inbuf, stdin ))
        newline = strchr( inbuf, '\n' );
  }
  else
  {
    /**
     * Zero out the newline character and convert to the target
     * data type using strtol.  The chk parameter will point
     * to the first character that isn't part of a valid integer
     * string; if it's whitespace or 0, then the input is good.
     */
    newline = 0;

    char *chk;
    int tmp = strtol( inbuf, &chk, 10 );
    if ( isspace( *chk ) || *chk == 0 )
    {
      myInt = tmp;
    }
    else
    {
      printf( "%s is not a valid integer!\n", inbuf );
    }
  }
}
else
{
  // error reading from standard input
}

Interactive input in C can be simple xor it can be robust. You can't have both.

And somebody really needs to fix formatting on IE.

John Bode
  • 119,563
  • 19
  • 122
  • 198