Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Simple Problem

Status
Not open for further replies.

sedawk

Programmer
Feb 5, 2002
247
US
In the following code:

Code:
#include <stdio.h>

main()
{
    char ch;
    while (TRUE) {
        scanf("%c",ch);
        if (ch == 'a') printf("Yes");
    }
}

Very simple code but the behavior is strange: it seems only take one in every two inputs, or ignore the other. It is better to run it and know what I am saying. Why? The compiler is VC6++.
 
The problem is similar to the problem I had with cin::getline() (Read: faq116-5193). I suppose that cin::getline() was written based on Microsoft's weird implementation of scanf().

Anyway, what happened is that when you are reading user input using scanf(), you are actually reading the input from the stdin's internal buffer (not directly from the keyboard). The input flow should be something like this.

keyboard --> stdin's buffer --> your scanf()

So let's say that user presses 'a' then enter. In the stdin's internal buffer, the input stored is "a\n". Your first scanf() picks up 'a'. What's left in the stdin buffer is "\n".

Then, the user keys in the second input 'b' then enter. The content of the stdin buffer right now is "\nb\n". Thus, your second scanf() picks up '\n' (left over from previous input) instead of 'b'. That's why your scanf() seems to skip.

To solve the problem, you should flush the stdin buffer after scanf() - using fflush() or fflushall().
 
fflush(stdin) still doesn't cure the problem. I think your explanation is right though: it seems one extra "\n" attach the key input.

Even getchar() in VC6++ has the same problem.
 
> scanf("%c",ch);
Well for a start, it should be [tt]scanf("%c",&ch);[/tt]

And fflush(stdin) is undefined.
It might appear to do something for you, but it sure doesn't do anything useful for me.

It's one of those annoying MS extensions which only they support. People then get confused when they realise they've learnt an implementation rather than a language.

--
 
fflush(stdin) is indeed undefined according to the C standard. However, VC++ 6.0 is not really 100% standard compliant. In fact, some of VC++ 6.0's C/C++ standard library is implemented in a 'different' way (Some of them are bugs according to Microsoft). Their closest product to the C/C++ standard compliance so far is VC++ 7.0 (or Visual Studio .NET), which is "98% standard compliant" - meaning that there are still some differences from the C/C++ standard. So, I suppose we really can't complain much.

Anyway, so far I can think of two possible workarounds to your problem. We can flush the buffer manually or we can use '%1s' in your scanf().

To flush the buffer manually, we can do something like this.

Code:
...[green]//partial codes[/green]
scanf(%c,&ch);

[green]//manually flushing the stdin[/green]
while(getchar()!='\n') [green]//in case if there are other input[/green]
   continue; 
getchar(); [green]//get rid of the the '\n'[/green]
 
...[green]//remaining codes[/green]

Or you can use '%1s' instead of '%c' in your scanf().
 
Correction in the codes ...

while(getchar()!='\n') continue;

should do fine in getting rid of the '\n'. There is no need for additional getchar() after that.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top