Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: how do I remove bad input from cin?

Tags:

c++

iostream

I have done some cin operation and before I use cin I want to clear its state and flush it. How do I do it? I know cin.clear() clears the error state but to flush the cin buffer how do I check if it's empty and if not which of the below statements shall I use to empty it so that I can safely use cin later?

cin.ignore(std::numeric_limits<std::streamsize>::max()); 

or

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
like image 711
ajay Avatar asked Feb 14 '23 22:02

ajay


1 Answers

It seems, you detected a problem and you want to get rid of erronous input, e.g., the entered line. You could try to get rid what std::cin has in its buffer but generally, this doesn't work too well as there is no guarantee that the stream has read, e.g., a complete line. Also, to make it potentially useful you'll need to make sure that stdin and std::cin are not synchronized as otherwise std::cin will never buffer any characters anyway:

std::ios_base::sync_with_stdio(false);
// read data using std::cin

if (!std::cin) {
    // clean-up
    std::cin.clear();
    if (std::cin) {
        std::cin.ignore(std::cin.rdbuf()->in_avail()); // ignore what is buffered
    }
}

Whether in_avail() will return a non-zero value depends entirely on the used stream buffer and it may ignore more than you actually want to ignore anyway. For example, if std::cin's stream buffer is replaced to use the stream buffer of an std::istringstream it will probably consume all the character from this source.

Probably the most sensible clean-up is to ignore() the next character or the characters on the current line, using either

std::cin.ignore();

or

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

The max() of std::streamsize is used as a magical number to indicate that the count should not be considered a termination criteria. If you don't pass a termination character the stream will ignore characters until the end of the stream which is probably not what you want.

like image 81
Dietmar Kühl Avatar answered Feb 27 '23 15:02

Dietmar Kühl