cin.clear and cin.ignore

When inputting 123.456 in 3 separate lines. Shouldn't the output be 1#123.456#123 instead of 1#23.456#123? How does the the cin.clear and ignore affect the digit "1" that disappeared?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  #include <iostream>
using namespace std;



int main()
{
	char letter;
	int n;
	float m;
	
	
	
	cin >> letter;
	cin >> m >> n;
	
	cin.clear();
	cin.ignore(200, '\n');
	
	cin >> n;	 
	cout << letter << "#" << m << "#" << n << endl;   
	

}
When inputting 123.456 in 3 separate lines.

What do you mean? Can you show us how you input that in 3 separate lines?
Maybe that was too specific. I said 3 lines because you have to input 123.456 3 times in the console.
How does the the cin.clear and ignore affect the digit "1" that disappeared?
It doesn't. The digit '1' didn't disappear, it was read into char letter and is displayed in the resulting output as the first character.


When entering values at the keyboard, each keystroke is stored in a buffer.
at the prompt
 
    cin >> letter;
the user types "123.456\n"
The digit '1' is stored in letter and the buffer now contains "23.456\n".

Next, the line cin >> m reads the "23.456" into the float value m. The buffer now contains just "\n".

next, the rest of that statement >> n; tries to read an integer. It consumes and discards the newline '\n' and waits for the user to enter a value.
The user types "123.456\n", so the integer part "123" is stored in the n, and the buffer now contains ".456\n".

Next the line
 
    cin.clear();
resets any error flags which may have been set for the cin stream (for example if the user types a non-numeric character when a number is expected, the fail flag is set), and
 
    cin.ignore(200, '\n');
will read and discard up to 200 characters from the input buffer, or until a newline is read. That will consume all of the ".456\n" from the buffer so it is now empty.

Finally, the line cin >> n; again prompts for the integer, the user enters "123.456\n", integer n receives 123 and the buffer contains ".456\n".
Last edited on
Hello gl3nnn,

I have found that the cin.clear and cin.ignore do not always work the way you might think. More often it will cause you to enter something more than one.

Not long ago I read something that said you only need to use cin.clear and cin.ignore after a cin >> something and before a call to getline. A program I was working on the time did support that concept.

Remove lines 17 and 18 and see what happens.

Hope that helps,

Andy
closed account (48T7M4Gy)
cin to getline is a particular case and the rule of thumb above is generally right.

However in the OP case and applying Chervils commentary this is one way of doing it to ensure valid input:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>

using namespace std;

int main()
{
    char letter;
    int n;
    float m;
    
    cout << "Input a letter: ";
    cin >> letter;
    cin.ignore(256, '\n'); // ensures only one character read
    
    
    cout << "Enter a float: ";
    while(!(cin >> m))
    {
        cout << "Must input a float\n";
        cin.clear(); // clear error flag
        cin.ignore(256, '\n'); // ignores remainder of stream
    }
    
    
    cout << "Enter an integer: ";
    while(!(cin >> n))
    {
        cout << "Must input an integer\n";
        cin.clear(); // clear error flag
        cin.ignore(256, '\n'); // ignores remainder of stream
    }
    
    cout << letter << "#" << m << "#" << n << endl;
    
    return 0;
}


http://www.cplusplus.com/reference/istream/istream/ignore/
Note 256 is arbitrarily large but is not absolutely correct.
If this is exactly numeric_limits<streamsize>::max(), there is no limit: As many characters are extracted as needed until delim (or the end-of-file) is found.
Last edited on
Topic archived. No new replies allowed.