clearing the cin buffer

I'm trying to understand what happens when users enter data from cin. I read some information about clear() and ignore() functions, but I didn't understand they. I'm wondering whether using getline() is right for clearing de buffer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

void clearCin()
{
    string temp;
    getline(cin, temp);
}

int main()
{
    string myStr;
    cin >> myStr;
    cout << myStr << endl;
    clearCin();
    cin >> myStr;
    cout << myStr << endl;

    return 0;
}
It is possible to break cin or force it into "failed state"
How?
The example below will force cin into "failed state"
1
2
3
int number

cin >> number

User Input
q

Basically, number is an int type variable and it is only designed to store an integer. Once user enters a non-integer such as 'q', cin enters the "failed state" and input operations are no longer possible unless you terminate the program or you somehow correct it and force cin out of the failed state.

That is when you use "cin.clear ()". It basically restores the state of cin. "cin.ignore ()" can be used to "ignore" any other garbage that input stream might contain after cin.clear () has been used.

This is one example of how you can utilize cin.clear () and cin.ignore () together.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int number;

cout << "Enter an Integer: ";
cin >> number;

// User types any char or string of length < 100

// Because input stream is in a failed state, cin will be evaluated to false
while ( !cin )
{
    cin.clear ();    // Restore input stream to working state
    cin.ignore ( 100 , '\n' );    // Get rid of any garbage that user might have entered
    cout << "I said enter an integer, Dumbass. Try again: ";
    cin >> number;    // After cin is restored and any garbage in the stream has been cleared, store user input in number again
}



Here is a sample run:
1
2
3
4
5
6
7
Enter an Integer: t
I said enter an integer, Dumbass. Try again: werewewrweaar
I said enter an integer, Dumbass. Try again: dfd
I said enter an integer, Dumbass. Try again: 4

Process returned 0 (0x0)   execution time : 6.552 s
Press any key to continue.


So, i guess in a sense, cin.ignore () is the function that you would use to "clear the buffer"...



EDIT: Btw, getline () is used to store a "line" or sentence. It is capable of storing blank spaces. But, it cannot really store newlines.

Here is a very simple use of getline ()
1
2
3
4
5
6
7
8
string sentence;

cout << "Enter a sentence: ";
getline ( cin , sentence );

cout << "Your sentence is " << sentence << endl;

return 0;


Sample Run:
1
2
3
4
5
Enter a sentence: I'm a Programmer!
Your sentence is I'm a Programmer!

Process returned 0 (0x0)   execution time : 6.414 s
Press any key to continue.
Last edited on
Thanks, mpark4656!

If I'm asking for string values, cin can't get into failed state. Am I wrong? Then, is still necessary to use clear()?
If I'm asking for string values, cin can't get into failed state. Am I wrong?

Yes you are wrong. Any input stream will enter a fail state if eof() is detected, and it is possible to signal eof() on the cin stream.

Here is a reference for ios::clear.

http://www.cplusplus.com/reference/ios/ios/clear/


You would use cin.clear () function if you suspect that ios error will occur at any point during program execution.


I wrote this short program to demonstrate how the error state flag of input stream is set. If you want, I suggest that you copy this code and compile on your own computer.
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
37
38
39
40
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
    std::ifstream inFile;

    std::string fileName;   // Stores the file name provided by user

    std::cout << "Enter the name of text file you would like to open: ";
    std::cin >> fileName;

    fileName += ".txt";   // Add the extension

    inFile.open ( fileName );


    if ( inFile.fail () )
        std::cout << "The state flag of file input stream is set to fail.\n";
    else
        std::cout << "The state flag of the file input stream is NOT set to fail.\n";

    if ( inFile.bad () )
        std::cout << "The state flag of file input stream is set to bad.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to bad.\n";

    if ( inFile.good () )
        std::cout << "The state flag of file input stream is set to good.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to good.\n";

    if ( inFile.eof () )
        std::cout << "The state flag of file input stream is set to eof.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to eof.\n";

    return 0;
}



Here is the first sample run: As you notice, I ran the program and provided "test" for the file name and "test.txt" is NOT in the same directory as the program. Therefore, the program is unable to open the file and fail bit was set.
1
2
3
4
5
6
7
8
Enter the name of text file you would like to open: test
The state flag of file input stream is set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is NOT set to good.
The state flag of file input stream is NOT set to eof.

Process returned 0 (0x0)   execution time : 1.276 s
Press any key to continue.


Here is the second sample run: I created a text file and named it "test.txt". Then, I ran the program and provided the same file name. Notice now that the input file stream is error-free and the bit is set to good.
1
2
3
4
5
6
7
8
Enter the name of text file you would like to open: test
The state flag of the file input stream is NOT set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is set to good.
The state flag of file input stream is NOT set to eof.

Process returned 0 (0x0)   execution time : 1.500 s
Press any key to continue.



More Tests coming in a minute.
Last edited on
Now, take a look at this code. I created two variables. One is a string and the other is an integer. This time, test.txt file has
test

As you already know, the string "test" cannot be stored in an integer variable, but in this program, I will force it. See what happens.
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
37
38
39
40
41
42
43
44
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
    std::ifstream inFile;

    std::string fileName;   // Stores the file name provided by user

    std::string word;
    int number;

    std::cout << "Enter the name of text file you would like to open: ";
    std::cin >> fileName;

    fileName += ".txt";   // Add the extension

    inFile.open ( fileName );

    inFile >> number;     // string can't be stored in number variable.

    if ( inFile.fail () )
        std::cout << "The state flag of file input stream is set to fail.\n";
    else
        std::cout << "The state flag of the file input stream is NOT set to fail.\n";

    if ( inFile.bad () )
        std::cout << "The state flag of file input stream is set to bad.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to bad.\n";

    if ( inFile.good () )
        std::cout << "The state flag of file input stream is set to good.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to good.\n";

    if ( inFile.eof () )
        std::cout << "The state flag of file input stream is set to eof.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to eof.\n";

    return 0;
}




Sample Run 1: Force the program to store a string in integer variable from the file and observe which bit is set
1
2
3
4
5
6
7
8
Enter the name of text file you would like to open: test
The state flag of file input stream is set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is NOT set to good.
The state flag of file input stream is NOT set to eof.

Process returned 0 (0x0)   execution time : 1.702 s
Press any key to continue.



Sample Run 2: Now, change the code so that the program stores the string, "test" in the string variable and observe the state flag. Notice that now, the input stream is set to EOF (End of File). That is because there was only one word in the text file and I just yanked it using >>, so the eof bit was set. Because the string was stored in an appropriate variable, fail bit was not set.
1
2
3
4
5
Enter the name of text file you would like to open: test
The state flag of the file input stream is NOT set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is NOT set to good.
The state flag of file input stream is set to eof.



Sample Run 3: Now, I am going to use the following line and attempt to read from the same file even though there is no more items.
inFile >> word >> word;
1
2
3
4
5
6
7
8
Enter the name of text file you would like to open: test
The state flag of file input stream is set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is NOT set to good.
The state flag of file input stream is set to eof.

Process returned 0 (0x0)   execution time : 1.492 s
Press any key to continue.

This time, both the fail and eof bits are set. EOF was set because with the first inFile >> word; triggered the end of file. The extra inFile >> word; has triggered the fail bit.


Last edited on
Finally, I will now use the clear function.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
    std::ifstream inFile;

    std::string fileName;   // Stores the file name provided by user

    std::string word;
    int number;

    std::cout << "Enter the name of text file you would like to open: ";
    std::cin >> fileName;

    fileName += ".txt";   // Add the extension

    inFile.open ( fileName );

    inFile >> word >> word;

    if ( inFile.fail () )
        std::cout << "The state flag of file input stream is set to fail.\n";
    else
        std::cout << "The state flag of the file input stream is NOT set to fail.\n";

    if ( inFile.bad () )
        std::cout << "The state flag of file input stream is set to bad.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to bad.\n";

    if ( inFile.good () )
        std::cout << "The state flag of file input stream is set to good.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to good.\n";

    if ( inFile.eof () )
        std::cout << "The state flag of file input stream is set to eof.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to eof.\n";


    std::cout << "\n\n****Now, I am going to execute inFile.clear () **** \n\n";

    inFile.clear ();

    if ( inFile.fail () )
        std::cout << "The state flag of file input stream is set to fail.\n";
    else
        std::cout << "The state flag of the file input stream is NOT set to fail.\n";

    if ( inFile.bad () )
        std::cout << "The state flag of file input stream is set to bad.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to bad.\n";

    if ( inFile.good () )
        std::cout << "The state flag of file input stream is set to good.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to good.\n";

    if ( inFile.eof () )
        std::cout << "The state flag of file input stream is set to eof.\n";
    else
        std::cout << "The state flag of file input stream is NOT set to eof.\n";

    return 0;
}


Sample Run:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Enter the name of text file you would like to open: test
The state flag of file input stream is set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is NOT set to good.
The state flag of file input stream is set to eof.


****Now, I am going to execute inFile.clear () ****

The state flag of the file input stream is NOT set to fail.
The state flag of file input stream is NOT set to bad.
The state flag of file input stream is set to good.
The state flag of file input stream is NOT set to eof.

Process returned 0 (0x0)   execution time : 1.720 s
Press any key to continue.



Hope this helped.
Last edited on
Yes, mpark4656, sure it will help me. Thanks again!
Topic archived. No new replies allowed.