Error Handling issue with cin.fail() - c++

If I input a character 's' for instance, why does this still go into an infinite loop prompting me for ""How many people are playing? (1-5): "?
int getnumplayers(){
int num_players =0;
while(true){
cout<<"How many people are playing? (1-5): ";
//cin.ignore();
cin>>num_players;
if(cin.fail()){
cout<<"hello";
}
else if((num_players < 6 && num_players > 0)){
break;
}
}
return num_players;
}

once cin.fail() is set, you need to clear it with cin.clear() before cin is willing to read again. So, it's skipping over your requests for reads because the stream is not "good".
I think you want the line
cin.clear(cin.rdstate() & ~ios_base::failbit);
cin.ignore();
in your if(cin.fail()) block.

Related

Why the loop is not breaking and also the if condition isnt working as expected?

#include"std_lib_facilities.h"
int main()
{
int i = 0;
int len_password;
cout<<"How Long Should Be Your Password?\n";
while(i == 0){
cin>>len_password;
if(!cin && len_password > 15){
cout<<"Please enter an appropriate value:\n";
}
else{
break;
cout<<"success!";
}
}
}
I want this code to print success when the loop breaks...and the loop will only break if the condition in if statement is satisfied....but even after typing the right input the loop is not breaking and also when i enter wrong input it is not allowing me to input once again...
If you checking it's less then 15 then print should be before the break and you don't need the !cin
You need to print "success" before breaking out of the loop. Also, your check for !cin doesn't make sense.
Instead, you could check if the cin operation failed, and if so, you can clear the stream to take additional input:
while(!(std::cin >> len_password) || len_password > 15)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Please enter an appropriate value:\n";
}
cout << "success";
The loop will keep executing until the user enters an appropriate value, and then "success" is printed outside the loop. This avoids any break statements within the loop.

How to skip 'enter' in cin.ignore()

I write a code to check char 'exit' in int cin. But I find that I need to set delimiters in cin.ignore such as '\n' and input it when running command and I think that is not friendly.
How can I change the code to skip the extracting step , maybe using other code instead of cin.ignore?
Sorry for everyone who try to read my English and answer as I not a native English user.
I mean cin.ignore is to extracts and discards characters until the given character is found, is it have a way to clear the cin buffer in C++ with discarding characters without extracting?
void checkcin(int &y)
{
string input = "", ans;
cin.clear();
cin.ignore(INT_MAX, '\n');
getline(cin, input);
while (input == "exit")
{
cout << "Are you sure to exit: ";
cin >> ans;
if (ans == "yes")
{
cout << "Bye." << endl;
exit(0);
}
else if (ans == "no")
{
cout << "Then welcome back!";
cout << "Input again: ";
cin >> input;
}
}
y = std::stoi(input);
}
The first parameter in the "std::cin.ignore()" that you are using just comes down to a very large number. This should be the maximum number of characters that the input buffer can hold. This number may be different on different systems or even header files for different compilers.
You need to press enter twice because there is nothing in the buffer to ignore. It is waiting for something to be entered to ignore. some people will use this to pause the program before the "return 0;".

How to make the user enter a positive double variable?

I want the user to enter a positive double variable. If they enter anything else, I want the program to loop and continue to ask them to enter a number instead of getting an error and closing. I made an infinite loop with a conditional statement and a break. For some reason if they enter something other than a positive number it infinitely asks for the the radius. Can someone help me with this?
for(;;) {
cout << "Radius: ";
cin >> radius;
if(radius > 0){
break;
}
}
You can simply check the stream state of cin:
double radius;
for(;;) {
cout<<"Radius: ";
if(!(cin>>radius) || radius < 0.0) {
cout << "Invalid input, please enter a positive double value." << endl;
cin.clear();
std::string dummy;
cin >> dummy; // Read the left invalid input
}
else {
break;
}
}
You need to clear the stream's error flags, otherwise you keep looping, since no more other reads are performed when the stream is in a bad state, and radius keeps its value before the loop. You need to do the following (must #include <limits>):
if(!(cin >> radius)) // we didn't read a number, cin has a "bad" state
{
cin.clear(); // clear the error flags
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // ignore the rest
continue;
}

newline character left in the cin.get() buffer

I am using cin.get(input).ignore(INT_MAX, '\n'); in my code. this statement is being called in a while loop to choose an option in a menu.
Although I am using ignore chained with cin.get() for every input I am reading in, sometimes a newline character remains in the cin buffer and I should press an extra 'Enter' to go to the normal process of the while loop for choosing an option.
what should I do to solve this problem?
int Menu::getChoice(int menuNum) // getChoice() returns users menu choice
{
int i = 0;
char input;
while(0 == i) // As long as users choice not valid
{
cout << "Make your choice: ";
cin.get(input).ignore(INT_MAX, '\n');
if (!cin.good())
{
cin.clear();
cin.ignore(INT_MAX, '\n');
}
i = atoi(&input);
if (menuNum == 1)
{
if (i < 1 || i > 2)
{
cout << "Not a valid choice!" << endl;
i = 0;
}
}
}
return i;
}
If I understand correctly, this issue is that sometimes in order for the code to move past cin, and to get the assignment for input, two new line characters are needed. If this is correct, than if you replace:
cin.get(input).ignore(INT_MAX, '\n');
with this:
cin >> input;
the issue will be resolved.

checking for user integer input with cin gives infinite loop

I'm trying to print an error message if the user does not enter anything into the input prompt, and if what they enter is zero or less.
void checkScoreInputed(int* qaltScores, int i){
while(true){
// cin.clear(); here?
if ((cin >> qaltScores[i]) && (qaltScores > 0)){
// also tried placing cin.clear() here.
break;} else // else is optional
cout << "Please supply a positive number for the score: ";
}
}
I've tried placing cin.ignore() and cin.clear() both before and after the if statement, but I am still getting an infinite loop of cout << "Please supply...." after the user enters a non-integer value, like a character. How can I fix this?
You forgot the [i] in
if ((cin >> qaltScores[i]) && (qaltScores[i] > 0))
^^^
Without it, you're checking the value of the pointer, not the number you've just read.
You also need to call cin.clear() and cin.ignore().
void checkScoreInputed(int* qaltScores, int i) {
while(true) {
if ((cin >> qaltScores[i]) && (qaltScores[i] > 0)){
break;
}
cout << "Please supply a positive number for the score: ";
cin.clear();
cin.ignore(10000,'\n');
}
}
See Why would we call cin.clear() and cin.ignore() after reading input?