-->

C: Multiple scanf's, when I enter in a value f

2018-12-31 12:06发布

问题:

This question already has an answer here:

  • scanf() leaves the new line char in the buffer 3 answers

I have this block of code (functions omitted as the logic is part of a homework assignment):

#include <stdio.h>

int main()
{
    char c = \'q\';
    int size; 

    printf(\"\\nShape (l/s/t):\");
    scanf(\"%c\",&c);

    printf(\"Length:\"); 
    scanf(\"%d\",&size);

    while(c!=\'q\')
    {
        switch(c)
        {
            case \'l\': line(size); break; 
            case \'s\': square(size); break;
            case \'t\': triangle(size); break; 
        }


        printf(\"\\nShape (l/s/t):\");
        scanf(\"%c\",&c);

        printf(\"\\nLength:\"); 
        scanf(\"%d\",&size);
    }

    return 0; 
}

The first two Scanf\'s work great, no problem once we get into the while loop, I have a problem where, when you are supposed to be prompted to enter a new shape char, it instead jumps down to the printf of Length and waits to take input from there for a char, then later a decimal on the next iteration of the loop.

Preloop iteration:

Scanf: Shape. Works Great
Scanf: Length. No Problem

Loop 1.

Scanf: Shape. Skips over this
Scanf: length. Problem, this scanf maps to the shape char.

Loop 2
Scanf: Shape. Skips over this
Scanf: length. Problem, this scanf maps to the size int now.

Why is it doing this?

回答1:

scanf(\"%c\") reads the newline character from the ENTER key.

When you type let\'s say 15, you type a 1, a 5 and then press the ENTER key. So there are now three characters in the input buffer. scanf(\"%d\") reads the 1 and the 5, interpreting them as the number 15, but the newline character is still in the input buffer. The scanf(\"%c\") will immediately read this newline character, and the program will then go on to the next scanf(\"%d\"), and wait for you to enter a number.

The usual advice is to read entire lines of input with fgets, and interpret the content of each line in a separate step. A simpler solution to your immediate problem is to add a getchar() after each scanf(\"%d\").



回答2:

The basic problem is that scanf() leaves the newline after the number in the buffer, and then reads it with %c on the next pass. Actually, this is a good demonstration of why I don\'t use scanf(); I use a line reader (fgets(), for example) and sscanf(). It is easier to control.

You can probably rescue it by using \" %c\" instead of \"%c\" for the format string. The blank causes scanf() to skip white space (including newlines) before reading the character.

But it will be easier in the long run to give up scanf() and fscanf() and use fgets() or equivalent plus sscanf(). All else apart, error reporting is much easier when you have the whole string to work with, not the driblets left behind by scanf() after it fails.

You should also, always, check that you get a value converted from scanf(). Input fails — routinely and horribly. Don\'t let it wreck your program because you didn\'t check.



回答3:

Use the function

void seek_to_next_line( void )
{
    int c;
    while( (c = fgetc( stdin )) != EOF && c != \'\\n\' );
}

to clear out your input buffer.



回答4:

Try adding a space in the scanf.

scanf(\" %d\", &var);
//     ^
//   there

This will cause scanf() to discard all whitespace before matching an integer.



回答5:

The \'\\n\' character is still left on the input stream after the first call to scanf is completed, so the second call to scanf() reads it in. Use getchar().



回答6:

When you type the shape and ENTER, the shape is consumed by the first scanf, but the ENTER is not! The second scanf expects a number so, the ENTER is skipped because is considered a white space, and the scanf waits for a valid input ( a number) that, again, is terminated by the ENTER. Well, the number is consumed, but the ENTER is not, so the first scanf inside the while uses it and your shape prompt is skipped... this process repeats. You have to add another %c in the scanfs to deal with the ENTER key. I hope this helps!



回答7:

You can also use scanf(\"%c%*c\", &c); to read two characters and ignore the last one (in this case \'\\n\')



标签: c scanf