tags:

views:

167

answers:

2

Whenever I do a scanf before a fgets the fgets instruction gets skipped. I have come accross this issue in C++ and I remember I had to had some instrcution that would clear the stdin buffer or something like that. I suppose there's an equivalent for C. What is it?

Thanks.

+5  A: 

I'll bet it's because of the \n stuck in the input stream.

See one of these questions:

I am not able to flush stdin.
How do I go about Flushing STDIN here?
scanf() causing infinite loop

or this answer.

Also: Why not to use scanf().

P.S. fgets() is a function, not an instruction.

aib
+2  A: 

The fgets() function following the call to scanf() is probably1 not getting skipped. It is probably1 returning immediately having found a newline in the input stream.

Calling scanf() before fgets() almost always results in scanf() leaving an unused newline ('\n') in the input stream, which is exactly what fgets() is looking out for.

In order to mix scanf() and fgets(), you need to remove the newline left behind by the call to scanf() from the input stream.

One solution for flushing stdin (including the newline) would be something along the lines of the following:

int c;
/* discard all characters up to and including newline */
while ((c = getchar()) != '\n' && c != EOF); 

1 - It is difficult to be certain without seeing the actual code.


Or, as Jerry Coffin suggested in his comment below, you could use scanf("%*[^\n]");. The "%*[^\n]" directive instructs scanf() to match things that are not newlines and suppress assignment of the result of the conversion.

/* match up to newline */
scanf("%*[^\n]"); 
/* discard the newline */
scanf("%*c"); 

From http://c-faq.com/stdio/gets_flush1.html:

An initial scanf() with “%*[^\n]” will either eat everything up to but not including a newline, or fail. A subsequent “%*c” (or plain old getchar()) will consume the newline, if there was one.

That last “if” matters too: perhaps the user signalled EOF. In this case, the getchar() or scanf("%*c") might -- this decision is left to the people who write your compiler -- either immediately return EOF, or go back to the user for more input. If the implementors choose the latter, the user might have to click on “end this thing” (^D, ^Z, mouse button, front panel switch, or whatever) one extra time. This is annoying, if nothing else.


Or, as Chris Dodd suggested in his comment below, you could use scanf("%*[^\n]%*1[\n]");. The "%*[^\n]%*1[\n]" directive instructs scanf() to match things that are not newlines and then match one newline and suppress assignment of the results of the conversion.

/* match and discard all characters up to and including newline */
scanf("%*[^\n]%*1[\n]");
jschmier
You can flush the input buffer (i.e., discard until newline is reached) a little more easily with: `scanf("%*[^\n]");`
Jerry Coffin
You can flush up to and including the newline with `scanf("%*[^\n]%*1[\n]")`
Chris Dodd