C/C ++ Study Notes 3-in-depth analysis of CIN (II)-Troubleshooting of CIN (original)

Source: Internet
Author: User

Gain a deep understanding of the mechanism of CIN error handling, and gain a deep understanding of functions such as cin. Clear/cin. Ignore/cin. Good/cin. Fail.

In the previous section, we mentioned in several examples that the CIN function has an error, so that no read operation is performed (Program 8 ). We often see functions such as cin. Clear (), Cin. Ignore (), Cin. Fail () in the program. These functions are related to the troubleshooting of CIN errors. This section analyzes the error handling mechanism of CIN and learns several important functions: cin. fail (), Cin. bad (), Cin. good (), Cin. clear (), Cin. ignore.

 

During program execution, a flag variable is used to indicate the input exception status. Three flag spaces are used to indicate three types of exception information: failbit, eofbit, and badbit. These three flags are allocated in the flags:
____________________________________
| 2 | 1 | 0 |
| Failbit | eofbit | badbit |
| ___________ | __________ | ___________ |
Let's take a look at the functions of these signs (reference msdn ):
Badbit, to record a loss of integrity of the stream buffer.
Eofbit, to record end-of-file while extracting from a stream.
Failbit, to record a failure to extract a valid field from a stream.
In addition, a useful value is goodbit, where no bits are set.

Next, let me take a look at several data definitions for iOS classes (reference msdn ):
Typedef T2 iostate;
Static const iostate badbit, eofbit, failbit, goodbit;

Here, the IOS class defines the four constants badbit, eofbit, failbit, and goodbit. In fact, these four mark constants are used to take the mask of the corresponding flag, that is, the four input exceptions!
The values of the preceding four constants are as follows:
IOS: badbit 001 input (output) stream fatal error, irreparable
IOS: eofbit 010 has reached the end of the file
IOS: failbit 100 input (output) stream non-fatal error, recoverable
IOS: goodbit 000 the stream status is completely normal, and each abnormal flag is 0

We can use the output statement to verify the values of these constants:
Cout <IOs: failbit <Endl;
Cout <IOs: eofbit <Endl;
Cout <IOs: badbit <Endl;
Cout <IOs: goodbit <Endl;
The output result is:
4
2
1
0
[Note] They are not the storage variables of failbit, badbit, eofbit, and goodbit, but constants that mark four abnormal states, in fact, they are equivalent to taking the mask of the corresponding status flag. If the flag variable is flag, the flag & failbit gets the Fail flag.

After figuring out the principle of the Flag bit, let's look at several functions about the exception flag:

1. iostate IOs: rdstate ()
Taking the value of the Flag variable, we can use this function to obtain the value of the entire flag variable, and then obtain the status of the corresponding flag bit with the constant phase of the Flag bit defined above. For example:
Void testflags (IOS & X) // obtain the three flag status of the x stream
{
Cout <(X. rdstate () & IOS: badbit) <Endl;
Cout <(X. rdstate () & IOS: failbit) <Endl;
Cout <(X. rdstate () & IOS: eofbit) <Endl;
Cout <Endl;
}

2. bool IOs: fail () const;
1 Or true if rdstate & failbit is nonzero, otherwise 0 or false. (Reference msdn)
Rdstate indicates the value of the identifier variable obtained through rdstate (). It is consistent with failbit, that is, the value of the failbit flag is obtained. If the result is not zero, true is returned. Otherwise, false is returned. That is, this function returns the failbit status and returns the flag status through the bool value.

3. bool IOs: Bad () const;
1 Or true if rdstate & badbit is nonzero; otherwise 0. (Reference msdn)
Similar to fail.

4. bool IOs: Good () const;
1 Or true if rdstate = goodbit (no state flags are set), otherwise, 0 or false. (Reference msdn)
If the function is set to goodbit, that is, if all three flag bits are 0 (that is, there is no exception), true is returned. Otherwise, false is returned.

5. Void IOs: clear (iostate _ state = goodbit );
This function is used to reset the identifier variable. _ state is used to reset the value. The default value is goodbit, that is, all flag spaces are cleared by default. You can also pass in parameters, such as clear (failbit), so that the identifier variable is set to failbit (that is, 001 ).
We usually use its default value. When CIN encounters an exception, we use this function to reset all flag spaces. If CIN encounters an exception and the flag is not reset, the next CIN operation cannot be performed. For example, Test 2 of Program 2 in the previous section, why is the second input operation not executed? In Program 8, why is ch not executed? This is why !!!
Therefore, Cin. Clear () is often used in the program. to reset the error mark!

6. Another function, void IOs: setstate (iostate _ State );
This function is also used to set the identifier variable, but it is different from clear. Clear () is a sign that clears all the signs and is set to a new parameter. This function does not clear other flags, but only positions the corresponding flags of the parameters. This function is not frequently used and will not be described here.
 

After figuring out these functions, I have a deep understanding of the error handling of the CIN input operation. Next, let's take a look at the test in the previous section of Program 8. The first time Getline () was used to read the string too long, this caused an exception. You can check the flag to verify it! Therefore, the subsequent CIN> CH statement is not executed. Then we use the clear () function we learned to force the error mark reset to see what will happen?
Program 9:
# Include <iostream>
Using namespace STD;
Int main ()
{
Char CH, STR [20];
Cin. Getline (STR, 5 );
Cout <"flag1:" <cin. Good () <Endl; // check the goodbit status, that is, whether an exception exists.
Cin. Clear (); // clear the error mark
Cout <"flag1:" <cin. Good () <Endl; // clear the flag and check the exception status.
Cin> CH;
Cout <"str:" <STR <Endl;
Cout <"ch:" <ch <Endl;
Return 0;
}
Test input:
12345 [enter]
Output:
Flag1: 0 // good () returns false, indicating an exception
Flag2: 1 // good () returns true indicating that clear () has cleared the error mark
STR: 1234
Ch: 5
[Analysis] after the program is executed, only one read operation is performed. Cin> CH still does not read data from the keyboard, but it is different from Program 8, the ch value is '5', and the error mark is clearly displayed before CIN> CH, that is, the read operation of CIN> CH is actually executed. This is how CIN reads data: it directly retrieves data from the input buffer. In this example, enter "12345" for the first time, while Getline (STR, 5) takes only the first four characters in the buffer zone according to the '5' parameter, so STR takes "1234 ", the character '5' is still in the buffer, so CIN> CH gets data directly from the buffer and does not read data from the keyboard!
That is, if the buffer is not cleared after the current data reading error, the reset error mark is not enough! It would be nice to clear the residual data in the buffer zone! Next let's look at a very important function!

7. basic_istream & ignore (streamsize _ COUNT = 1, int_type _ delim = traits_type: EOF ());
Function: causes a number of elements to be skipped from the current read position.
Parameters:
_ Count, the number of elements to skip from the current read position.
_ Delim, the element that, if encountered before count, causes ignore to return and allowing all elements after _ delim to be read. (Reference msdn)
This function is used to discard characters in the input buffer. The first parameter defines a number, and the second parameter defines a character variable. The following explains how the function is executed: The function constantly retrieves a character from the buffer and determines whether it is _ delim. If not, it discards the character and counts it. When the Count reaches _ count, it exits, if yes, discard the character and exit. For example: cin. Ignore (5, 'A'); the function will continue to discard a character from the buffer until the number of discarded characters reaches 5 or the read character is 'A '. The following is a program example:
Program 10:
# Include <iostream>
Using namespace STD;
Int main ()
{
Cin. Ignore (5, 'A ');
Return 0;
}
Test 1 input:
C [enter]
C [enter]
C [enter]
C [enter]
C [enter]
The program ends.
[Analysis] the buffer zone is empty at the beginning of the program, Cin. if ignore () is used to retrieve data from the buffer, the request is input from the keyboard. Each time a character is input from the keyboard. If it is not 'a', the request is discarded. Therefore, five times are input in this test, until the Count reaches 5.

Test 2 input:
C [enter]
C [enter]
A [enter]
The program ends.
[Analysis] the first two characters are not 'a' discarded and the count does not reach 5. The third input is 'A'. The program stops dropping this character!

Discard one character:
Let's take a look at the default value of this function. The first parameter defaults to 1, and the second parameter defaults to EOF. Therefore, Cin. Ignore () is the first character in the buffer zone to be discarded, which is also commonly used in programs! Let's look at program 5 and program 5 using cin. get () reads characters. The first time a carriage return is read, The get function does not discard the carriage return. Therefore, the carriage return remains in the buffer zone. As a result, the second time the data is read, the carriage return is obtained directly from the buffer zone! This is inconsistent with what we initially used, since cin. get () will not automatically discard the carriage return at the end of the input. Here we have learned the ignore () function, and we can manually request it! So program 5 can be changed as follows:
Procedure 11:
# Include <iostream>
Using namespace STD;
Int main ()
{
Char C1, C2;
Cin. Get (C1 );
Cin. Ignore (); // by default, a character is discarded, that is, the carriage return that ended last time.
Cin. Get (C2 );
Cout <C1 <"" <C2 <Endl; // print two characters
Cout <(INT) C1 <"" <(INT) C2 <Endl; // print the ASCII values of the two characters
Return 0;
}
Test 1 input:
A [enter]
B [enter]
Output:
A
B
97 98
[Analysis] the program will be normal!

Clear the entire buffer zone:
In fact, the most common method for this function is to set the first parameter to a very large value and set the second parameter to '/N ', in this way, all the residual data in the carriage return in the buffer zone can be used, because the input residual data is useless in general, therefore, it is reasonable to clear all data in the buffer before a new input operation.
For example, Cin. Ignore (1024, '/N ');
Or: cin. Ignore (STD: numeric_limits <STD: streamsize >:: max (), '/N ');
(STD: numeric_limits <STD: streamsize >:: max () should be the maximum value defined. I don't know the specific value, so I don't want to mislead you any more. Please give me some advice !)

 

| ------------------ This section ends, and the next section is continuing ------------------- |
| ----------- The article is original to the author. Please indicate the source or author for reprinting! ------------ |
| ------------------------------------------------------------------- |
| ---------- If you have any questions, please criticize and correct them. You are welcome to exchange and learn --------- |
| ------------ Lewsn2008@yahoo.com.cn, QQ: 44452114 ------------- |
---------------------------------------------------------------------

 

 

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.