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 enter, if the user entered an integer,
The program will output the entered integer, and prompt the user to enter an integer again, and then wait for the user to enter.
However, if you do not enter an integer (such as a decimal number or a letter), assume 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 does not wait for user input and reads data directly from the buffer. However, the buffer contains letters,
This letter is left in the buffer again, so it is repeated, resulting in the constant output of "Please input an integer: 2 ".
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 using 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 says:
Fflush on input stream is an extension to the C standard (the input stream of the fflush operation 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 stream points to the output stream or update stream ),
The operation recently executed by the update stream is not input,
The fflush function then transfers any data to be written in the stream to the host environment (host environment) to write the 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);/* You can directly use this code as an alternative to ffldio (stdio) and directly run the command to clear the input cache stream */
/* 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 ++
This article is copyrighted by ant's C/C ++ standard programming and the author antigloss. For more information, see the original author and source. Thank you.
Http://bbs.linuxtone.org/thread-112-1-1.html