1. Why is fflush (stdin) incorrect?
First, check the following program:
# Include <stdio. h>
Int main (void)
{
Int I;
For (;;){
Fputs ("Please input an integer:", stdout );
Scanf ("% d", & I );
Printf ("% d/N", I );
}
Return 0;
}
This program will first prompt the user to enter an integer, and then wait for the user to input. If the user inputs an integer, the program will output the integer just entered and prompt the user to enter an integer again, then wait for user input. However, once the user does not input an integer (such as a decimal number or a letter), assuming that the last integer obtained by the scanf function is 2, the program will continuously output "Please input an integer: 2 ". This is because scanf ("% d", & I); can only accept integers. If you enter a letter, this letter will be left in the "input buffer. Because there is data in the buffer, the scanf function will not wait for user input and read it directly in the buffer. However, it is a letter in the buffer, and this letter is left in the buffer again and again, as a result, "Please input an integer: 2" is output continuously ".
Some people may say, "In this case, add 'fflush (stdin); 'to the scanf function to clear the input buffer. Isn't that enough ?" However, this is wrong! Fflush (stdin) has never been defined in the C and C ++ standards ). Some people may say, "but I used fflush (stdin) to solve this problem. How can you say it is wrong ?" Indeed, some compilers (such as vc6) Support fflush (stdin) to clear the input buffer, but not all compilers must support this function (GCC in Linux does not support this function ), because fflush (stdin) is not defined in the standard at all ). The msdn document clearly states that fflush on input stream is an extension to the C standard (the fflush operation input stream is an extension of the C standard ). Of course, if you don't care about program portability, using fflush (stdin) is no big problem. The following is the definition of fflush function in c99:
Int fflush (File * stream );
If the stream points to the output stream or update stream, and the update stream
If the most recent operation is not input, the fflush function transfers any data to be written in the stream
Host environment writes data to a file. Otherwise, its behavior is undefined.
The original article is as follows:
Int fflush (File * stream );
If stream points to an output stream or an update stream in which
The most recent operation was not input, the fflush function causes
Any unwritten data for that stream to be delivered to the host environment
To be written to the file; otherwise, the behavior is undefined.
The host environment can be understood as the operating system or kernel.
From this we can see that if stream points to the input stream (such as stdin), then the behavior of the fflush function is uncertain. Therefore, using fflush (stdin) is incorrect, at least because of poor portability.
2. How to clear the input buffer
Although fflush (stdin) cannot be used, we can write code to clear the input buffer. You only need to add a few simple codes after the scanf function.
/* C version */
# Include <stdio. h>
Int main (void)
{
Int I, C;
For (;;)
{
Fputs ("Please input an integer:", stdout );
Scanf ("% d", & I );
If (feof (stdin) | ferror (stdin ))
{/* If you enter the end mark of a file (or the file has been read ),*/
/* Or a read/write error occurs, exit the loop */
/* Do something */
Break;
}
/* If no error occurs, clear the input stream. */
/* "Eat" the remaining data in the input stream through the while loop */
While (C = getchar ())! = '/N' & C! = EOF );
/* Use scanf ("% * [^/n]"); you can also clear the input stream ,*/
/* Does not contain N characters. */
Printf ("% d/N", I );
}
Return 0;
}
/* C ++ version */
# Include <iostream>
# Include <limits> // to use numeric_limits
Using STD: cout;
Using STD: Endl;
Using STD: CIN;
Using STD: numeric_limits;
Using STD: streamsize;
Int main ()
{
Int value;
For (;;)
{
Cout <"enter an integer :";
Cin> value;
If (CIN. EOF () | cin. Bad ())
{// If you enter the end mark of a file (or the file has been read ),
// Or if a read/write error occurs, exit the loop.
// Do something
Break;
}
// When an invalid character is read, the input stream is in the error state,
// To continue obtaining input, call the clear function first.
// To clear the error mark of the input stream before calling
// Ignore function to clear data in the input stream.
Cin. Clear ();
// Numeric_limits <streamsize>: max () returns the input buffer size.
// The ignore function clears the data in the input stream.
// You can query the specific usage of these two functions by yourself.
Cin. Ignore (numeric_limits <streamsize>: max (), '/N ');
Cout <value <'/N ';
}
Return 0;
}
References:
ISO/IEC 9899: 1999 (E) programming languages-C 7.19.5.2 the fflush Function
The C programming language 2nd edition by kernighan & Ritchie
ISO/IEC 14882 () programming languages ages-C ++