Why does scanf ask for input twice, but just in th

2019-08-01 08:03发布

问题:

First of all, this may seem duplicate with this question, but in my case, why did this only happen in the 1st loop iteration (input for the 1st array element). Why not all?

My code:

#include "stdio.h"

int main(int argc, char const *argv[])
{
    int a[5];
    int i;
    for (i = 0; i < 5; i++) {
        printf("Input a[%d]:\n", i);
        int x = scanf("%d ", &a[i]);    // notice the white-space after %d
    }
    for (i = 0; i < 5; ++i)
    {
        printf("a[%d]=%d\n", i, a[i]);
    }
}

Output example:

Input a[0]:
1
2
Input a[1]:
3
Input a[2]:
4
Input a[3]:
5
Input a[4]:
6
a[0]=1
a[1]=2
a[2]=3
a[3]=4
a[4]=5

Why did it ask for input twice only for a[0] but not for the rest, and also why the value assigned to a[1-5] is the value that was input in the one loop iteration before it?

I read this answer, but I still don't understand why it didn't ask for input twice in each loop. Any clear explanation?

回答1:

In your case,

 scanf("%d ", &a[i]);

after scanning an integer, scanf() needs to match the white space, and any number of white space until a non-white space character is required to complete the match.

So, for the first time, the second input is the non-white space, which terminates the scan, but left in the buffer (remains unread) for the next scan.

Next time onwards, the last input (left in the buffer) is considered as the scanned input , and the current input works as the terminator, just to be left in the buffer and so on.

So, the very last input (6), is never actually read into the array, that remains as a mere terminator. The sequential first five inputs are considered. Just to make it clear, quoting from C11, chapter §7.21.6.2, paragraph (5), emphasis mine

A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read.



回答2:

@Sourav Ghosh very nicely explained about scanf().

To clarify the user experience, the tricky additional part is that stdin is typically line buffered. That means none of the user typing is given to stdin until Enter or EOF occurs. That is why the first scanf() did not return when 2 was typed (the non-white-space sought by directive " " in scanf("%d ",...). User has to type 2 and Enter, then stdin gets both "2\n". Then scanf() sees the 2, leaves it unread in stdin and then returns.



回答3:

the following code:

1) raises no compiler warnings I.E. complies cleanly

2) properly handles any error condition with scanf()

3) properly handles the program exit with 'return(0);'

4) includes stdlib.h for exit() and EXIT_FAILURE

5) properly declares the main() function when the optional parameters argc and argv are not used.

6) corrects the problem with the format string in scanf()

#include "stdio.h"
#include <stdlib.h> // exit and EXIT_FAILURE

#define MAX_A_LEN (5)

int main( void )
{
    int a[ MAX_A_LEN ];
    int i; // loop index

    for (i = 0; i < MAX_A_LEN; i++)
    {
        printf("Input a[%d]:\n", i);
        if( 1 != scanf("%d", &a[i]) )    
        { // then scanf failed
            perror( "scanf failed" );
            exit( EXIT_FAILURE );
        }

        // implied else, scanf successful
    }

    for (i = 0; i < MAX_A_LEN; ++i)
    {
        printf("a[%d]=%d\n", i, a[i]);
    }

    return(0);
} // end function: main


标签: c scanf