, Wonderful! C/C ++ misunderstanding 2: fflush (stdin)

Source: Internet
Author: User
12:02:00
1. Why? Fflush(Stdin) Yes

See the followingProgram:

# 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 enter an integer (such as a decimal or letter), assumeScanfThe last integer obtained by the function is2, Then the program will continuously output"Please input an integer: 2". This is becauseScanf ("% d", & I );Only integers are allowed. If you enter a letter, the letter will be left in"Input buffer. BecauseBufferThere is data, soScanfThe function will not wait for user input, but read it directly in the buffer, but it is a letter in the buffer. This letter is left in the buffer again and again, so that the output will not stop"Please input an integer: 2".

 

Someone may say, "this is the case. Scanf Add' Fflush(Stdin); ' Input buffer Just clear it ?" However, this is wrong! C And C ++ Of Standard Has never been defined in Fflush(Stdin) . Someone may say, "but I use Fflush(Stdin) How can you say yes to solve this problem ?" Indeed, Some Compiler (such Vc6 ) Supported Fflush(Stdin) To clear the input buffer, but not all compilers must support this function ( Gcc Just Not Supported), because the standard is not defined at all. Fflush(Stdin) . Msdn The document also clearly states FflushOn input stream isExtensionTo the c Standard ( Fflush The input stream of the operation isC Standard Expansion ). Of course, if you don't care about the program Portability , Use Fflush(Stdin) There is no big problem. Below is C99 Pair Fflush Function Definition:

 

IntFflush(File*Stream);

 

IfStreamPointOutput streamOrUpdate stream(Update stream), and the update stream
The most recent operation is not input.FflushThe function will transmit any data to be written in the stream
Host environment writes data to a file. Otherwise, its behavior isUndefined.

The original article is as follows:


IntFflush(File*Stream);

If stream points to an output stream or an update stream in which
The most recentOperation was not input,FflushFunction causes
Any unwritten data for thatStream 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.

 

We can see that ifStreamPoint to the input stream (for exampleStdin), ThenFflush The behavior of a function is uncertain. ThereforeFflush(Stdin)Is incorrect, at least YesPoor portability.

 

 

    1. 2.ClearInput bufferMethod

 

Though not availableFflush(Stdin)But we can write it by ourselves.CodeTo clearInput buffer. You only needScanfAdd a few simple codes to the function.

/* C version */
# Include<Stdio. h> 


int main (void)
{< br> int I, C;
for (;)
{< br> fputs (" Please input an integer: ", stdout);
scanf (" % d ", & I);

If (feof ( stdin ) | ferror ( stdin )
{ /* If you enter the end mark (or the file has been Read ), */
/* or read/write error , exit the loop */
/* Do something */
break;
}< br> /* 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]"); (For details, see the following remarks.) You can also clear the input stream, */

/* Will remain\ NCharacter. */

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 ()
{< br> int value;
(;;)
{< br> cout <"enter an integer:";
CIN> value;
If (CIN. EOF () | cin. bad ()
{// If the user inputsEnd mark(Or the file has beenRead),
// Or occursRead/write errorsTo exit the loop.

// Do something
Break;
}
// after an invalid character is read, the input stream is in the error status ,
// to continue obtaining the input, you must call the clear function
// to clear the error mark of the input stream before calling the
// ignore function to clear data in the input stream.
cin. Clear ();
// Numeric_limits<Streamsize>: Max () returns the size of the input buffer.
// 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 ages- C 7.19.5.2FflushFunction

The C programming language 2nd edition by kernighan & Ritchie

ISO/IEC 14882 () programming languages ages- C ++

****************************************
Note ①:

Asterisk (*) indicates reading data of the specified type but not saving

[] Scanning character set combination-Regular Expression, character cluster: When ^ is used in a set of brackets, it indicates "not" or "excluded.
[^ \ N] defines a set, that is, any character except '\ N'

Note: The ansi c standard adds a new feature to scanf () called scan set ). The scan set defines a character set combination that can be read by scanf () and assigned to the corresponding character array. A scan set is defined by a string of characters in square brackets. It must be prefixed with a percent sign before the left square brackets. For example, the following scan set causes scanf () to read characters A, B, and C:
% [ABC]
When using the scanning set, scanf () continuously eats the characters in the set and puts them in the corresponding character array until it finds that the characters are not in the Set (that is, the scanning set only reads matching characters, if any mismatch is found, return immediately ). When returned, the array contains a string ending with null and composed of read characters.
Char Nums [20] = "";
Scanf ("% [0-9]", Nums );
Character ^ can be used to describe the complement set. When the ^ character is placed as the first character of the scan set, it forms a complementary set of commands consisting of other characters, indicating that scanf () only accepts unspecified other characters.
For other information, see regular expressions.

   
Example
Xiaou posted comments on 14:09:40
# Include <iostream>
# Include <stdexcept> // standard library exception class
# Include <limits> // to use numeric_limits
Using namespace STD;
Int main ()
{
Int A, B;
While (1 ){
Cin> A> B;
Try {
If (CIN. Good () cout <a + B <Endl;
Else throw runtime_error ("incorrect input. Try again? Y or N :");
}
Catch (runtime_error ERR ){
Cout <err. What ();
Char ch;
Cin. Clear ();
Cin. Ignore (numeric_limits <streamsize>: max (), '\ n ');
Cin> CH;
If (CIN. Bad () | ch! = 'Y') break;
}
} // Whlie ()
System ("pause ");
}

   

 

Another example: C and C ++ mixed cache clearing method (recommended)
Xiaoyou (tourist) commented on 12:20:26

# Include <iostream>
Using namespace STD;

template
class input {
T;
Public:
input (char * S, T min, T max) {
cout while (1) {
If (CIN> T)
If (T <= max & T> = min)
break;
// C and C ++:
cin. clear ();
int C;
while (C = getchar ())! = '\ N' & C! = EOF);

}
}
};

Int main ()
{
Input <int> O ("test",-1, 10 );
System ("pause ");
}

 

A better method for C ++:
2009-5-19 22:16:34
1. Use cin. Clear () to clear the error status.
2. Use cin. Sync () to clear the input cache.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.