Question

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")
Was it helpful?

Solution

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.

OTHER TIPS

Whitespace is a delimiter for 5y3 %s format specifier, and newline is regarded as whitespace, so it remains buffered. Console input is normally line oriented, so a subsequent call to getchar() will return immediately because a 'line' remains buffered.

scanf("%s", command );
while( getchar() != '\n' ){ /* flush to end of input line */ }

Equally if you use getchar() or %c to get a single character you normally need to flush the line, but in this case the character entered may itself be a newline so you need a slightly different solution:

scanf("%c", ch );
while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ }

similarly for getchar():

ch = getchar();
while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ }

The sensible thing to do of course is to wrap these solutions into stand-alone specialised input functions that you can reuse and also use as a place to put common input validation and error checking code (as in Daniel Fischer's answer which sensibly checks for EOF - you would normally want to avoid having to duplicate those checks and error handling everywhere).

I'd rather first use fgets and then use sscanf to parse the input. I have been doing this stuff like this for a long time and the behaviour has been more predictable than using plain scanf.

Well, I have something easier: add another getchar() ... problem solved!!

after taking command input flush the stdin.

fflush(stdin);

but flushing a input stream results in undefined behavior (though Microsoft's C library defines the behaviour as an extension).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top