How to Reset Std::Cin When Using It

How to reset std::cin when using it?

You could use, when the condition, std::cin.fail() happens:

std::cin.clear();
std::cin.ignore();

And then continue with the loop, with a continue; statement. std::cin.clear() clears the error flags, and sets new ones, and std::cin.ignore() effectively ignores them (by extracting and discarding them).

Sources:

  1. cin.ignore()
  2. cin.clear()

Resetting cin stream state C++

After cin.clear(), you do this:

#include <iostream> //std::streamsize, std::cin
#include <limits> //std::numeric_limits
....
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')

What the above does is that it clears the input stream of any characters that are still left there. Otherwise cin will continue trying to read the same characters and failing

Why doesn't std::cin.clear() work in this simple program?

That's because std::cin::clear clears the error state of cin but it does not remove the data from the stream. You can use std::cin::ignore() to read and discard a line of text before reading values_to_compute.

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

Make sure to #include <limits> to get std::numeric_limits.

Why can't use std::cin by setting std::cin.clear() after a wrong input?

clear just resets the error-flags, but it leaves the previous input, which had led to the failure, in the buffer. Hence, the second cin >> n will again read the same input and will again fail. So you will not get the chance to enter new input.

You need to take errorneous characters from the buffer (in addition to calling cin.clear()); Use, for example, cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'), which ignores every character until the first occurence of a \n. You could also use fgets, but - in contrast to ignore - fgets requires a buffer to store characters in which you are actually not interested.

How do I flush the cin buffer?

Possibly:

std::cin.ignore(INT_MAX);

This would read in and ignore everything until EOF. (you can also supply a second argument which is the character to read until (ex: '\n' to ignore a single line).

Also: You probably want to do a: std::cin.clear(); before this too to reset the stream state.

std::cin.clear() fails to restore input stream in a good state

Add this line after clearing cin:

std::cin.ignore();

This way, the stream ignores whatever is left on its buffer.

Stop cin from continuing to take in inputs

Ok, it turns out I simply had to put the cin.clear() statement before the cin.ignore() statement. I don't know why this is the case so if someone could explain it I would be grateful.

Why would we call cin.clear() and cin.ignore() after reading input?

The cin.clear() clears the error flag on cin (so that future I/O operations will work correctly), and then cin.ignore(10000, '\n') skips to the next newline (to ignore anything else on the same line as the non-number so that it does not cause another parse failure). It will only skip up to 10000 characters, so the code is assuming the user will not put in a very long, invalid line.

std::cin loops even if I call ignore() and clear()

When the stream is in an state of error,

  cin.ignore();

does not do anything. You need to call cin.clear() first before calling cin.ignore().

Also, cin.ignore() will ignore just one character. To ignore a line of input, use:

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

Add

#include <limits>

to be able to use std::numeric_limits.

The fixed up block of code will look something like:

int num;
while ( !(cin >> num) ) {
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Enter valid number: " << endl;
}

Resetting the State of a Stream

The code here

std::cin.clear(std::istream::failbit);

doesn't actually clear the failbit, it replaces the current state of the stream with failbit.

To clear all the bits, just call clear().


The description in the standard is a bit convoluted, stated as the result of other functions

void clear(iostate state = goodbit);

Postcondition: If rdbuf()!=0 then state == rdstate(); otherwise rdstate()==(state | ios_base::badbit).

Which basically means that the next call to rdstate() will return the value passed to clear(). Except when there are some other problems, in which case you might get a badbit as well.

Also, goodbit actually isn't a bit at all, but has the value zero to clear out all the other bits.

To clear just the one specific bit, you can use this call

cin.clear(cin.rdstate() & ~ios::failbit);

However, if you clear one flag and others remain, you still cannot read from the stream. So this use is rather limited.



Related Topics



Leave a reply



Submit