Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
1,453 Views

how to flush stdin buffer between two scanf?

Hi, 

 

I think this is a beginner-level question. Much appreciate your answers in advance! 

 

The following is my simple C-code: 

 

#include <stdio.h># include <string.h> void main(void) { char sex; char area; do { printf("Please select your area (QLD, NSW, ACT, SA, WA, NT or TAS): "); scanf("%s", area); } while(strcmp(area,"QLD")!= 0 && strcmp(area,"NSW")!= 0 && strcmp(area,"ACT")!= 0 && strcmp(area,"SA")!= 0 && strcmp(area,"WA")!= 0 && strcmp(area,"NT")!= 0 && strcmp(area,"TAS")!= 0); do { printf("Please enter your sex (M/F): "); scanf("%c", &sex); } while(sex != 'M' && sex != 'F') ; }  

 

This problem is: the prompt "Please senter your sex (M/F)" always gets printed twice on the screen before a value is entered. I realized it is because when I enter the string for area, the last character ENTER gets stored in stdin buffer and is treated as the value for sex. To make the program function as expected, I have to insert another scanf("%c", &sex") between the two do-while loops to clear the stdin buffer. 

 

I tried to find a neater way to do this. Some online results suggest fflush(stdin) is not a good thing to do. 

 

Is there a better way to clear the stdin buffer, or a better coding structure to avoid such problem completely?
0 Kudos
4 Replies
Highlighted
Valued Contributor III
39 Views

I myself find another way to circumvent this problem. That is to declare sex as a string, that is char sex[2], as shown below: 

 

#include <stdio.h> # include <string.h> void main(void) { char sex; char area; do { printf("Please select your area (QLD, NSW, ACT, SA, WA, NT or TAS): "); scanf("%s", area); } while(strcmp(area,"QLD")!= 0 && strcmp(area,"NSW")!= 0 && strcmp(area,"ACT")!= 0 && strcmp(area,"SA")!= 0 && strcmp(area,"WA")!= 0 && strcmp(area,"NT")!= 0 && strcmp(area,"TAS")!= 0); do { printf("Please enter your sex (M/F): "); scanf("%s",sex); }while(strcmp(sex,"M")!= 0 && strcmp(sex,"F")!= 0); } 

 

In this way, a single ENTER character, even it is stored in sex, will not make strcmp TRUE and activate the do-while loop twice. And we don't need to clear stdin buffer. 

 

But this seems a waste. Every case for which we only need a character now needs to be replaced by a two-character string. Is there a better way?
0 Kudos
Highlighted
Valued Contributor III
39 Views

Any if I now type "yes" the program will crash. 

The simple solution is never to use scanf, and especially never with a %s format.
0 Kudos
Highlighted
Valued Contributor III
39 Views

Thank you for your reply,dsl! 

 

Do you imply I should always use cin and cout instead of scanf and printf? What if I have to write some code in a pure C environment?
0 Kudos
Highlighted
Valued Contributor III
39 Views

AARGGGG cin/cout are an order of magnitude worse. 

Not quite as bad as the stringstream classes though. 

 

Use fgets(buf, sizeof buf, stdin) to read a line and parse it yourself - in this case that just means that you need to allow for the trailinf '\n'. 

 

Lighter weight is to use read(0, buf, sizeof buf) - but that relies on the device drive code to generate lines (which it may not do).
0 Kudos