getchar does not stop when using scanf

oz123 picture oz123 · Sep 29, 2012 · Viewed 12.3k times · Source

I have a difficulty understanding getchar(). In the following program getchar works as expected:

#include <stdio.h>


int main()
{
    printf("Type Enter to continue...");
    getchar();
    return 0; 
} 

However, in the following program, getchar does not create a delay and the program ends:

#include <stdio.h>

int main()
{
    char command[100];
    scanf("%s", command );
    printf("Type Enter to continue...");
    getchar();
    return 0; 
} 

I have the following weired workaround, which works, but I don't understand why:

#include <stdio.h>

int main()
{
    char command[100];
    int i;
    scanf("%s", command );
    printf("Type Enter to continue...");
    while ( getchar() != '\n') {
      i=0; 
    }
    getchar();
    return 0;    
}

So my questions are:
1. What is scanf doing? Why does scanf do this ?
2. Why is my work around working?
3. What is a good way to emulate the following Python code:

raw_input("Type Enter to continue")

Answer

Daniel Fischer picture Daniel Fischer · Sep 29, 2012

The input is only sent to the program after you typed a newline, but

scanf("%s", command );

leaves the newline in the input buffer, since the %s(1) format stops when the first whitespace character is encountered after some non-whitespace, getchar() then returns that newline immediately and doesn't need to wait for further input.

Your workaround works because it clears the newline from the input buffer before calling getchar() once more.

To emulate the behaviour, clear the input buffer before printing the message,

scanf("%s", command);
int c;
do {
    c = getchar();
}while(c != '\n' && c != EOF);
if (c == EOF) {
    // input stream ended, do something about it, exit perhaps
} else {
    printf("Type Enter to continue\n");
    getchar();
}

(1) Note that using %s in scanf is very unsafe, you should restrict the input to what your buffer can hold with a field-width, scanf("%99s", command) will read at most 99 (sizeof(command) - 1)) characters into command, leaving space for the 0-terminator.