Why Would We Call Cin.Clear() and Cin.Ignore() After Reading Input

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.

When and why do I need to use cin.ignore() in C++?

Ignore is exactly what the name implies.

It doesn't "throw away" something you don't need instead, it ignores the amount of characters you specify when you call it, up to the char you specify as a breakpoint.

It works with both input and output buffers.

Essentially, for std::cin statements you use ignore before you do a getline call, because when a user inputs something with std::cin, they hit enter and a '\n' char gets into the cin buffer. Then if you use getline, it gets the newline char instead of the string you want. So you do a std::cin.ignore(1000,'\n') and that should clear the buffer up to the string that you want. (The 1000 is put there to skip over a specific amount of chars before the specified break point, in this case, the \n newline character.)

How to properly use cin.clear an cin.ignore

My issue is, if I cause an error it correctly drops into the else statement, but that is it. It will no longer run the rest.

The problem is in the line

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

The second argument needs to be a character, not a string.

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

Increase the warning level of your compiler to detect such errors.

By using g++ -std=c++11 -Wall, I get the following warning/error message.

socc.cc: In function ‘int main()’:
socc.cc:43:70: error: invalid conversion from ‘const char*’ to ‘std::basic_istream<char>::int_type {aka int}’ [-fpermissive]
cin.ignore(std::numeric_limits<std::streamsize>::max(), "\n");
^
In file included from /usr/include/c++/5/iostream:40:0,
from socc.cc:1:
/usr/include/c++/5/istream:657:5: note: initializing argument 2 of ‘std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::ignore(std::streamsize, std::basic_istream<_CharT, _Traits>::int_type) [with _CharT = char; _Traits = std::char_traits<char>; std::streamsize = long int; std::basic_istream<_CharT, _Traits>::int_type = int]’
basic_istream<char>::

cin.clear() and cin.ignore() won't work

You should use cin.fail() along with your conditions

if(cin.fail()||cityname1 == "Error" || cityname2 == "Error")
{
cout << "**********ERROR! PLEASE ENTER 0-5 FOR YOU LOCATIONS**********" << endl << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
detailLoop();
}

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 to ignore wrong cin input in C++?

OK. User input is hard.

Interactive user input is line based.

User inputs some values and then hits return. This flushes the stream and unblocks the readers to get the value from the stream. So you should design your input code to be line based.

The first question seems to be is all the input on one line or do they input the values with a return between each? You can determine this with some outut to the user then follow the rules defined by your instructions.

So lets do a line based input example:

do {
// Your instructions can be better.
std::cout << "Input: Row Col Answer <enter>\n";

// Read the user input. 1 Line of text.
std::string line;
std::getline(std::cin, line);

// convert user input into a seprate stream
// See if we can correctly parse it.
std::stringstream linestream(std::move(line));

// Notice we check if the read worked.
// and that the check_ok() returns true.
// No point in call check_ok() if the read failed.
if (linestream >> r >> c >> ans && check_ok(r, c, ans)) {
break;
}
std::cout << "Invalid Input. Please try again\n";
}
while(true);


Related Topics



Leave a reply



Submit