In this lesson I briefly touch upon cin.clear() & cin.ignore()
Let’s start a conversation about these functions in detail!
Who wants to start?
In this lesson I briefly touch upon cin.clear() & cin.ignore()
Let’s start a conversation about these functions in detail!
Who wants to start?
From what I got from this video and doing a quick search on google cin.clear() is used to clear the remaining code and errors. While cin.ignore() will remove input contents in the code to prevent any errors.
If I understand it correctly, having entered a non-number value, we must both clear the error and ignore anything anything else in the input stream that might cause further errors.
After some poking around on Google, from my understanding, I want to add cin.ignore()
can take parameters.
If you just use cin.ignore()
as is, then it only skips the first character it reaches.
But if you try cin.ignore(1000, \n)
, then it will skip the next 1000 characters or skip until it hits a new line.
You can put different parameters in, it can be cin.ignore(50, ' ')
, this way it will skip the next 50 characters or skip until it hits a space.
From what I understand in the video and what I’ve seen on the internet, what .clear(); does is to remove the errors in the data types entered, in other words is that if we put a character to an integer type this is an error and .clear(); eliminates that error. On the other hand, what .ignore(); does is ignore what is stored in the buffer to avoid reading errors.
My understanding from the video is cin.clear() is used to clear a set line or number of characters, while cin.ignore() is meant to ignore any error codes or lines that are considered by c++ as an error.
i tried both with std::cin and without, doesn;t seem to work. so i have no idea what they do.! run tripplex and input 4 integers. run again and input 2 integers and they both give a result. using space between integers of course.
My understanding is that cin.clear() clears the error status flags and cin.ignore() removes all characters left in the stream up to the new line character. Effectively when used in combination following an input error they reinstate the stream buffer ready for new input.
Did you figure this out for yourself?
From your description that is correct behaviour as the code currently stands. Regardless of the number of space separated integers entered each loop of the code can only extract the first 3 in the buffer as we are assigning 3 variables, any others would be left in the buffer untouched ready to be processed in the second loop of the program. If you enter less than 3 (say ‘1 2’ and press enter) then user input will still require a third input before executing the next line in the program. Integer input is always valid when we are trying to assign the input to integer variables.
The problem comes when a user enters a non numeric character (for example ‘a’), this causes an error flag to be set when trying to assign it to the integer variable and the character is not removed from the buffer. This results in an endless loop because the buffer is never emptied and user input does not occur again until it is.
This is why we use the cin.clear() and cin.ignore() pair of functions, to clear the error status and remove the offending character from the buffer so user input can occur again and the endless loop is prevented.
[EDIT]
I experimented with the cin.ignore function and I believe a better solution is to add the following parameters:
std::cin.ignore(256, '\n'); // removes all characters in the stream buffer up to the new line'
This will now remove all characters (limited to 256) up to the new line control character rather than just a single character as we previously had with no parameters. This has the added bonus of removing any extra valid characters (integers) entered over and above the three required ones, as highlighted by mortalwombat, as well as dealing with any erroneous alpha characters entered.
From my understanding, in this case, function std::cin.clear() clears the error where a character value is assigned to an integer variable, and function std::cin.ignore() clears the input stream buffer so that there is no other characters remaining to cause future error.
From my understanding and experimenting(removing the cin.ignore and clear).
It seems that cin.ignore, clears the error.
And also by using cin.clear it clears any other unnecessery letters to cause another error.
Because, when i removed those lines. And when I put letter into the program(to be an error).
It just became a infinite loop.
Also you can put in a digit in cin.ignore or clear, how much it can clear.
With my Google search, I found that cin.clear() clears any errors from the input and cin.ignore() will ignore invalid characters. Feel free to correct me if I misinterpreted anything.
I am unsure if my code is working properly, if I enter the digits, that are incorrect the code gives me the game over message and starts from the print intro section. However if i enter any letters the code runs through twice and prompts for input the third time. again starting from the into section. The while loop is
while (true) { PlayGame(); std::cin.clear(); std::cin.ignore(); }
EDIT; I added a value in the parenthesis as indicated by IanL, and that solved the issue i was having, as the program had to run through to clear for each alphabetic character entered previously.
Based on only a guess, cin.clear I think just removes an errors from appearing in the terminal and cin.ignore just doesn’t care and gets the value put in and plays it. If it’s wrong, its wrong and wont display any errors if anything but a number is put in?“¯_(ツ)_/¯“
In my opinion cin.clear() it role is clear The line that holds the answer and cin.ignore() it role is ignore the answer that is a character.
What I think “cin.ignore()” does is the programmer can choose to pass a number as an arguement up to 10,000 characters and “cin.ignore( )” would skip the number of characters given on that cin line. The “cin.clear()” would reset an error for any number type on cin.
So does ignore without the parameters just skip everything afterwards then without any parameters added in?
I found out that std::cin >> Input
can return bool
too. Actually it returns the same cin, which is an instance of class istream
and that inherits the casting-to-bool function. So it works!
Because of that I think it’s better to clear error flags and buffer right after we got error on incorrect input, i.e.:
if (!(std::cin >> GuessA >> GuessB >> GuessC))
{
std::cin.clear();
std::cin.ignore();
}
I think cin.clear removes clears the terminal of errors, and then cin.ignore is to ignore the incorrect inputs. Then the way we set them up inside the while statement, is as we’re playing the game, if we come across any incorrect inputs clear the errors, and then ignore the incorrect inputs, and keep going.
In any programming language, I think it is important to know where to look for references. I like to use cppreference for checking what the code performs in C++.
Looking for std::cin.ignore won’t give me any results, so I tried std::cin. That led me to std::istream, which has ignore as one of the member functions. Looking into it, I got the definition " Extracts and discards characters from the input stream until and including delim
." and parameters of the function:
count - number of characters to extract
delim - delimiting character to stop the extraction at. It is also extracted.
So I understand that ignore will extract and discard input characters up until a limit and considering a point to exit the extraction and discard (e.g. ignore(5, \n) will keep extracting and discarding character until it finds a new line, or until it extracts 5 characters.
For the std::cin.clear() , I looked only for clear(), and among the options, it seemed that std::istream.clear would be more coherent with std::cin.clear. Clicking on that, again the definition: "Sets the stream error state flags by assigning them the value of state
"
The state
parameter can be goodbit
, badbit
, failbit
and eofbit
, and by default it assigns goodbit
leading to clearing all the error state flags.
So, my understanding is that clear() will clean any errors that can happen if the user inputs an unexpected value (e.g. inputing a character where it should be a number).