Home > Software design >  why does the do while skip scanf when none digit character is inputted
why does the do while skip scanf when none digit character is inputted

Time:06-06

In c I have this snippet

    int n=0; 
    do {
        printf("random text\n");
        scanf("%d", &n); 
    } while ( n < 1 || n > 10);

when the user inputs anything other than a number the loop spams the printf without waiting for user input

why does this happen and how do I fix this

CodePudding user response:

When the user enters bad data, the un-converted data remains in the input buffer.

You then repeatedly attempt to convert that data to an integer, and fail each time, leading to infinite repetition.

You can clear the input buffer up to the next new-line in case of failure.

Personally, I generally prefer to read in a line to start with, then attempt to convert that with sscanf, on this general order:

char buffer[256];
do {
    fgets(buffer, sizeof(buffer), stdin);
} while (sscanf(buffer, "%d", &n) == 0 || n < 1 || n > 10);

Generally it's better to wrap the calls to fgets and sscanf up in a function though, so you can return some error indication when either one fails (since this doesn't check the return value from fgets it can/will continue trying to read, even if reading from the stream fails).

CodePudding user response:

You need to skip the current content of the buffer if it does not contain a valid number. For example

int n=0; 
do {
    printf("random text\n");
    if ( scanf("%d", &n) == 0 )
    {
        scanf( "%*[^\n]" );
    }    
} while ( n < 1 || n > 10);

Pay attention to that this prompt

    printf("random text\n");

is confusing when you expect from the user to enter a number.

In general you should also add a check for EOF. For example

int n=0; 
do {
    n = 0;
    printf("random text\n");

    int result = scanf("%d", &n);

    if ( result == 0 )
    {
        scanf( "%*[^\n]" );
    }
    else if ( result == EOF )
    {
        break;
    }  
} while ( n < 1 || n > 10);

if ( n == 0 ) exit( 1 );
//...
  • Related