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 (not supported by gcc3.2 ), 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 do not care about program portability, use
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 writes any unwritten data to the stream.
Point to the file (such as the standard output file stdout ). Otherwise, the behavior of the fflush function is uncertain.
Fflush (null) clears all output streams and the update streams mentioned above. If a write error occurs, fflush
The function will mark those streams with errors and return EOF. Otherwise, 0 is returned.
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
Fflush (stdin) is incorrect, at least it is not portable.
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 );
If (scanf ("% d", & I )! = EOF)
{/*? If the user entered an EOF? */
/* The while loop clears the remaining characters in the input buffer */
/* The reader can convert it into a macro or inline function as needed */
/* Note: inline functions are also defined in c99, and gcc3.2 supports */
While (C = getchar ())! = '/N' & C! = EOF)
{
;
}/* End of while */
}
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;
Int main ()
{
Int value;
For (;;)
{
Cout <"enter an integer :";
Cin> value;
/* When an invalid character is read, the input stream will be in the error state,
* To continue obtaining input, call the clear function first.
* To clear the error mark of the input stream before calling
* The ignore function is used to clear data in the input buffer. */
Cin. Clear ();
/* Numeric_limits <streamsize>: max () returns the buffer size.
* The ignore function clears the data in the input buffer.
* You can query the specific usage of these two functions by yourself. */
Cin. Ignore (STD: numeric_limits <STD: 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 ++