0

I am trying to make a function to check the input of the user and let them try again in case they enter a wrong kind of input.

So when I enter a wrong input into the function it throws me inside an infinite loop. What can I do to fix it?

I am allowed to use only getchar and scanf for user input.

int sizeOfField()
{
    int size,inputCheck,flag=0;

    while (!flag)
    {
        inputCheck= scanf(" %d ", &size );
        if ( inputCheck < 1 )
        {
            printf( "Invalid Input!\n" );
            printf( "Try agian");
        } else if (inputCheck == 1)
            flag=1;
    }
    return size;
}
Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
gabi939
  • 107
  • 2
  • 8
  • 1
    clear `stdin`. But again doing it right is a lot of work. Why not `fgets` and `strtol`? – user2736738 Dec 28 '17 at 18:12
  • Can you reformat your code and check your braces? It's unclear if you're performing the return prematurely within the while loop or not. – Walt Stoneburner Dec 28 '17 at 18:15
  • What is the 'wrong input' you are giving? and from code, you made such that, if scanf fails, again wait for the next input- i suppose , it will be in loop untill you give the correct input.. – Sudhee Dec 28 '17 at 18:18
  • this is what i want ...but scanf works only once for some reason and it makes the program run infinitely inside a loop – gabi939 Dec 28 '17 at 18:51

1 Answers1

2

allowed to use only getchar and scanf for user input.

Using fgets() would be better. But to live with that restriction ....


When scanf(" %d ", &size ); returns 0, the non-numeric input remains in stdin.

Code needs to consume the invalid input - that is missing from OP's code.

For consistency, even with good input, consume the rest of the line too. This code does not detect if trailing junk exists after the good input on the same line.

The 2nd space in " %d " is also a problem. A " " directs scanf() to read all white space until some non white space is detected. This means scanf(" %d ", &size ); will not return until something like "123\n4\n" is entered. The 4 is read, determined not to be a white space and put back for later input. Drop the trailing white-space from the format.

Code also has a problem should an input return EOF (end-of-file or rare input error). The function sizeOfField() has no way to convey end-of-file. Function could be re-defined or for now, simple exit the program.

int sizeOfField(void) {
  int inputCheck;

  do {
    int size;
    inputCheck = scanf("%d", &size);
    if (inputCheck == EOF) {
      break;
    }

    // consume rest of line
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);

    if (inputCheck == 1) {
      return size;
    }

    if (ch == EOF) {
      break;
    }

    // Non-numeric input occurred.
    printf("Invalid Input!\n" "Try again");
    fflush(stdout);
  }

  // No recovery possible
  exit(EXIT_FAILURE);  
}

Curiously this is a case where " %d" has benefit over "%d". When input is non-numeric, code is certain at least all leading white space (including '\n') are consumed. The specifications about what charterers are put back due to being non-numeric into stdin are problematic if more that one character needs to be "put back" into stdin. Without that assurance, while ((ch = getchar()) != '\n' && ch != EOF); may not consume all the offending non-numeric input.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • AFAIU the last paragraph - if we use `"%d"` and then enter `\nX` then as `scanf` failed due to non-numeric input `X` - it is not sure if it would put back only `X` or `\nX` as a result - when we right after that try to clear `stdin` it would consume `\n`. And then again run into problem. Is this so you meant? – user2736738 Dec 28 '17 at 19:36
  • I'm curious about your 'curiously' comment. Since `%d` skips over leading white space, just like a blank skips over white space, the space is a harmless but unnecessary addition — that provides no benefit, contrary to what you've trying to say. – Jonathan Leffler Dec 28 '17 at 19:37
  • @JonathanLeffler Perhaps. With `scanf("%d",...` and input `"\tx"` the conversion fails, `scanf()` returns 0. What is the specified `getchar()` return value? `'x'` or `'\t'`? – chux - Reinstate Monica Dec 28 '17 at 20:30
  • It is required to be `x`. The input skips leading white space unconditionally. The white space does not cause the conversion failure. See also [Is it possible for `fscanf()` to return zero and consume input at the same time?](https://stackoverflow.com/questions/47839125/is-it-possible-for-fscanf-to-return-zero-and-consume-input-at-the-same-time/47839515#47839515) – Jonathan Leffler Dec 28 '17 at 20:31
  • @JonathanLeffler That makes the most sense given C11 §7.21.6.2 6 & 7. Perhaps it was a faulty system I used that returned `'\t'`. – chux - Reinstate Monica Dec 28 '17 at 20:41
  • 1
    If you encountered a system that returned the tab and not the `x`, then yes, you encountered a system with a bug. It gets more interesting with a floating point conversion and `1.23E+N`; the N is not part of the number, but the E and the + can't be used because there is no number where the N occurs. BSD (macOS) has `getchar()` return the E; Linux (IIRC) returns the N. The bug is in BSD/macOS in terms of strict standard conformance; in terms of sense and sensibility, BSD is sensible. – Jonathan Leffler Dec 28 '17 at 20:50
  • @JonathanLeffler One more reason to use `fgets()` and then `sscanf()`, `strtok()`, `strtol()`, etc. – chux - Reinstate Monica Dec 28 '17 at 21:06
  • Yup; using a line reader ([`fgets()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html) or POSIX [`readline()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/readline.html)) and then parsing separately is usually the better way of processing the data. I usually avoid `strtok()` because it is "poisonous". The function using `strtok()` cannot be called (directly or indirectly) from a function that is already using `strtok()`, nor can it call a function (directly or indirectly) that also uses `strtok()`. That makes it unsuited for use in any library function. – Jonathan Leffler Dec 28 '17 at 21:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162127/discussion-between-chux-and-jonathan-leffler). – chux - Reinstate Monica Dec 28 '17 at 21:15