checking for user integer input with cin gives infinite loop - c++

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?

Related

Is cin.fail with my while loop causing my output to infinitely loop? [duplicate]

I'm writing a program where I get an integer input from the user with cin>>iUserSel;. If the user puts in a letter, the program goes to an infinite loop. I tried to prevent that with the code below, but the program goes to an infinite loop and prints out "Wrong! Enter a #!". How can I fix my program?
cin>>iUserSel;
while (iValid == 1)
{
if (cin.fail())
{
cin.ignore();
cout<<"Wrong! Enter a #!"<<endl;
cin>>iUserSel;
}//closes if
else
iValid = 0;
}//closes while
I found some information on this at Correct way to use cin.fail() and C++ cin.fail() question
, but I didn't understand how to use them to fix my issue.
When cin fails, you need to clear the error flag. Otherwise subsequent input operations will be a non op.
To clear the error flags, you need to call cin.clear().
Your code would then become:
cin >> iUserSel;
while (iValid == 1)
{
if (cin.fail())
{
cin.clear(); // clears error flags
cin.ignore();
cout << "Wrong! Enter a #!" << endl;
cin >> iUserSel;
}//closes if
else
iValid = 0;
}//closes while
I would also suggest you change
cin.ignore();
to
cin.ignore(numeric_limits<streamsize>::max(), '\n');
In case the user enters more than one letter.
The problem you are having is that you don't clear the failbit from the stream. This is done with the clear function.
On a somewhat related note, you don't really need to use the fail function at all, instead rely of the fact that the input operator function returns the stream, and that streams can be used in boolean conditions, then you could do something like the following (untested) code:
while (!(std::cin >> iUserSel))
{
// Clear errors (like the failbit flag)
std::cin.clear();
// Throw away the rest of the line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Wrong input, please enter a number: ";
}
Here's what I would recommend:
// Read the data and check whether read was successful.
// If read was successful, break out of the loop.
// Otherwise, enter the loop.
while ( !(cin >> iUserSel) )
{
// If we have reached EOF, break of the loop or exit.
if ( cin.eof() )
{
// exit(0); ????
break;
}
// Clear the error state of the stream.
cin.clear();
// Ignore rest of the line.
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Ask more fresh input.
cout << "Wrong! Enter a #!" << endl;
}

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.

Error Handling issue with cin.fail()

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.

Why do I get an infinite loop when I press a letter? How do I change for error checking?

Why do I get an infinite loop when I press a letter? How do I prevent my code from going into an infinite loop when error checking?
#include <iostream>
using namespace std;
int main()
{
int number;
cout << "Enter a number in the range 1-100: ";
cin >> number;
while (number > 1 || number < 100)
{
cout << "ERROR: Enter a value in the range 1-100: ";
cin >> number;
}
return 0;
}
Because std::cin is type safe, it knows that a letter is not a valid input for "int number". It raises an error flag in std::cin and any subsequent operation will fail and return immediately.
You'll need to check the error state and clear any error flag(s) before you can proceed.
See existing post Why do I get an infinite loop if I enter a letter rather than a number?
Thanks a lot y'all. I ended up going with this one.
while (!(cin >> number))
{
cout << "ERROR: Enter a value in the range 1-100: ";
//to clear input stream
cin.clear();
//to discard previous input
cin.ignore(1200, '\n');
cin >> number;
}

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;
}