Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
778 views
in Technique[技术] by (71.8m points)

c - Validation check with scanf does not work inside a loop

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!
" );
            printf( "Try agian");
        } else if (inputCheck == 1)
            flag=1;
    }
    return size;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 4 " 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()) != '
' && ch != EOF);

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

    if (ch == EOF) {
      break;
    }

    // Non-numeric input occurred.
    printf("Invalid Input!
" "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 ' ') 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()) != ' ' && ch != EOF); may not consume all the offending non-numeric input.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...