What Is Causing Infinite While Loop [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am creating a game for two people to play to guess a number, I had it working with an if statement, but if player 2 gets it wrong I would like them to be able to guess again until they get it right. I decided to use a while loop, but I am getting an infinite loop of text, what can I do to stop it?
Here is my code: (I have commented out the if statement while working on the while loop)
#include <iostream>
using namespace std;
int main() {
int player1; //Number variable 1
int player2; //Number variable 2
cout << "Player 1 type in a number between 1 and 100: "; //Asks player to enter a number
cin >> player1;
system("CLS");
cout << "Player 2 guess the number between 1 and 100: "; //Asks guess a number
cin >> player2;
while(player2 != player1)
{
cout << "Player 2 guess the number between 1 and 100: ";
}
system("pause");
system("pause"); //Keeps window on screen
return 0;
}
Also any feedback on how to make my code better would be highly appreciated.

You got two things wrong
The braces for the while loop.
You are not reading user input again in the loop.
Modify the loop as below..
while(player2 != player1)
{
cout << "Player 2 guess the number between 1 and 100: ";
cin >> player2;
}

The problem is that within the while loop you never change the value of player1 or player2. Hence if they are unequal the first time they will be forever unequal and the code will loop infinitely. To fix this you need to move the code which changes the values into the body of the loop. Hence the user has a chance to change the values.
do {
cout << "Player 2 guess the number between 1 and 100: "; //Asks guess a number
cin >> player2;
if (player2 == player1)
cout << "Correct!" << endl;
else
cout << "Wrong, try again" << endl;
} while(player2 != player1)

If you don't use an open brace after the while statement it only refers to the following expression.
Additionally, after the while you are not reading data from the user again, so how do you expect player2 to ever change?
In terms of code organisation it would be better to set player2 to something obviously invalid, like -1, and have the while at the beginning, without the previous read and if statement so it doesn't have to be special cased.

Try this...
do
{
cout << "Player 2 guess the number between 1 and 100: "; //Asks guess a number
cin >> player2;
} while (player2 != player1)

Your curly brackets are in the wrong position and you never read input from the player after the first time.
if you change it like this, the second player will be asked again.
....
while(player1 != player2){
cout << "Player 2 guess the number between 1 and 100: ";
cin >> player2;
}
In addition, you should add some basic error handling, for example checking if the cin.error() flag is set.

Your while has no brackets, which makes the line right after it repeat forever!
Put the cout and cin for player 2 guess inside a do-while loop and then verify the condition.
cout << "Player 1 type in a number between 1 and 100: "; //Asks player to enter a number
cin >> player1;
system("CLS");
do {
cout << "Player 2 guess the number between 1 and 100: ";
cin >> player2;
} while(player2 != player1);

In
while(player2 != player1)
{
cout << "Player 2 guess the number between 1 and 100: ";
}
Nothing in the loop ever changes player2 nor player1, so if the condition player2 != player1 was true, it will remain true.

The loop
while(player2 != player1)
{
cout << "Player 2 guess the number between 1 and 100: ";
}
is an endless loop, because the variables player2 and player1 are not changed inside of the loop. If the while condition is true when entering the loop, it will stay true forever.
UPDATE:
To allow player2 to guess repeatedly, and hence change the number that he guessed and get out of the while loop, add cin >> player2; after the cout statement:
while(player2 != player1)
{
cout << "Player 2 guess the number between 1 and 100: ";
cin >> player2;
}

Related

Repeatedly non-stop output when I input char into int variable [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 months ago.
Improve this question
The folowing code tells user to input their age, it is set to be input interger between 0 and 120, it is capable to deal with wrong input like 'M' or 133 or -1. Warning message goes like this:Warning message
case 1: // input age
cout << "Enter your age: ";
cin >> age;
if(age <= 0 || age > 120){ // if the input type or number was wrong, it goes here
while(1){
cout << "Invalid input! Please enter again" << endl << ">>>";
age = -1;
cin >> age;
if(age > 0 && age <= 120) {break;}
}
}
However, it'll go wrong if I input something like \ or [.
Repeating Warning message
How can I solve this?
By emptying the keyboard buffer before a new entry.
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int age;
cout << "Enter your age: ";
cin >> age;
while(age <= 0 || age > 120)
{
cout << "Invalid input! Please enter again" << endl << ">>>";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> age;
}
return 0;
}
lets walk through this.
You type in something wrong and enter the if clause.
In here you enter the while loop and ask the user again for a input. This input is instantly answered because there is still something in the input stream.
Therefore you need to flush the cin stream before asking again for an input (You can place the flush in for example line 4).
You should be able to clear the stream with a command like this:
How do I flush the cin buffer?
Unfortunately I'm not able to test that out by myself but you can give it a try and I hope it helps!

Infinite loop created when inputting "yy" into a char variable that should only take a single character such as 'y' or 'n', "nn" does not break code

The code in the cont function asks the user if they want to play my game again.
The code works when receiving proper character inputs such as 'y' or 'n' as well as their respective capital letter variants, and the else block works properly to loop the function if an invalid input such as 'a' or 'c' is entered.
However during a test run, an input of 'yy' breaks the code causing the program to infinitely loop, running not only this cont function but my game function as well.
choice is stored as a char variable. I am wondering why the code even continues to run upon inputting multi-character inputs such as 'yy' or 'yes'. What's interesting is 'nn', 'ny' and other variations of multi-character inputs that begin with 'n' causes no issues and properly results in the else if block running as intended. Which prints "Thanks for playing." then ends the program.
Can variables declared as char accept inputs greater than 1 character? Does it only take the first value? And if so why does 'yy' cause a loop rather than the program running as intended by accepting a value of 'y' or 'Y'? How can I change my program so that an input of 'yy' no longer causes issues, without specific lines targeting inputs such as 'yy' or 'yes'.
#include <iostream>
#include <string> // needed to use strings
#include <cstdlib> // needed to use random numbers
#include <ctime>
using namespace std;
// declaring functions
void cont();
void game();
void diceRoll();
// variable declaration
string playerName;
int balance; // stores player's balance
int bettingAmount; // amount being bet, input by player
int guess; // users input for guess
int dice; // stores the random number
char choice;
// main functions
int main()
{
srand(time(0)); // seeds the random number, generates random number
cout << "\n\t\t-=-=-= Dice Roll Game =-=-=-\n";
cout << "\n\nWhat's your name?\n";
getline(cin, playerName);
cout << "\nEnter your starting balance to play with : $";
cin >> balance;
game();
cont();
}
// function declaration
void cont()
{
cin >> choice;
if(choice == 'Y' || choice == 'y')
{
cout << "\n\n";
game();
}
else if (choice == 'N' || choice == 'n')
{
cout << "\n\nThanks for playing.";
}
else
{
cout << "\n\nInvalid input, please type 'y' or 'n'";
cont(); // calls itself (recursive function!!!)
}
}
void game()
{
do
{
cout << "\nYour current balance is $ " << balance << "\n";
cout << "Hey, " << playerName << ", enter amount to bet : $";
cin >> bettingAmount;
if(bettingAmount > balance)
cout << "\nBetting balance can't be more than current balance!\n" << "\nRe-enter bet\n";
} while(bettingAmount > balance);
// Get player's numbers
do
{
cout << "\nA dice will be rolled, guess the side facing up, any number between 1 and 6 : \n";
cin >> guess;
if(guess <= 0 || guess > 6 )
{
cout << "\nYour guess should be between 1 and 6\n" << "Re-enter guess:\n";
}
} while(guess <= 0 || guess > 6);
dice = rand() % 6+1;
diceRoll();
if (dice == guess)
{
cout << "\n\nYou guessed correctly! You won $" << (bettingAmount * 6);
balance = balance + (bettingAmount * 6);
}
else
{
cout << "\n\nYou guessed wrong. You lost $" << bettingAmount << "\n";
balance = balance - bettingAmount;
}
cout << "\n" << playerName << ", you now have a balance of $" << balance << "\n";
if (balance == 0)
{
cout << "You're out of money, game over";
}
cout << "\nDo you want to play again? type y or n : \n";
cont();
}
void diceRoll()
{
cout << "The winning number is " << dice << "\n";
}
Does it only take the first value?
Yes, the >> formatted extraction operator, when called for a single char value, will read the first non-whitespace character, and stop. Everything after it remains unread.
why does 'yy' cause a loop
Because the first "y" gets read, for the reasons explained above. The second "y" remains unread.
This is a very common mistake and a misconception about what >> does. It does not read an entire line of typed input. It only reads a single value after skipping any whitespace that precedes it.
Your program stops until an entire line of input gets typed, followed by Enter, but that's not what >> reads. It only reads what it's asked to read, and everything else that gets typed in remains unread.
So the program continues to execute, until it reaches this part:
cin >> bettingAmount;
At this point the next unread character in the input is y. The >> formatted extraction operator, for an int value like this bettingAmount, requires numerical input (following optional whitespace). But the next character is not numerical. It's the character y.
This results in the formatted >> extraction operator failing. Nothing gets read into bettingAmount. It remains completely unaltered by the >> operator. Because it is declared in global scope it was zero-initialized. So it remains 0.
In addition to the >> extraction operator failing, as part of it failing it sets the input stream to a failed state. When an input stream is in a failed state all subsequent input operation automatically fail without doing anything. And that's why your program ends up in an infinite loop.
Although there is a way to clear the input stream from its failed state this is a clumsy approach. The clean solution is to fix the code that reads input.
If your intent is to stop the program and enter something followed by Enter then that's what std::getline is for. The shown program uses it to read some of its initial input.
The path of least resistance is to simply use std::getline to read all input. Instead of using >> to read a single character use std::getline to read the next line of typed in input, into a std::string, then check the the string's first character and see what it is. Problem solved.
cin >> bettingAmount;
And you want to do the same thing here. Otherwise you'll just run into the same problem: mistyped input will result in a failed input operation, and a major headache.
Why do you need this headache? Just use std::getline to read text into a std::string, construct a std::istringstream from it, then use >> on the std::istringstream, and check its return value to determine whether it failed, or not. That's a simple way to check for invalid input, and if something other than numeric input was typed in here, you have complete freedom on how to handle bad typed in input.

For Loops (C++)

Assignment:
The program should ask the user to enter a positive number and display all numbers from 1 to the input value. If the number is not positive, an error message should show up asking the user to re - enter the number.
My specific problem:
For my program, if the user enters an incorrect number and then re - enters a positive number, it does not display all the numbers from 1 to the input value. The program just ends.
#include <iostream>
using namespace std;
int main()
{
int userChoice;
int i = 1;
cout << "Enter a positive integer" << endl;
cin >> userChoice;
if (userChoice > 0)
{
for (i = 1; i <= userChoice; i++)
{
cout << "Loop 1:" << endl;
cout << i << endl;
}
}
else if (userChoice < 0)
cout << "Please re - enter" << endl;
cin >> userChoice;
system("pause");
return 0;
}
You need some sort of loop at the top of your program, that keeps asking for input until the user provides something valid. It looks like a homework assignment, so I will provide pseudo-code, not something exact:
std::cout << "Enter a number:\n";
std::cin >> choice;
while (choice wasn't valid) { // 1
tell the user something went wrong // 2
ask again for input in basically the same way as above // 3
}
// after this, go ahead with your for loop
It is actually possible to avoid the duplication here for step 3, but I worry that might be a little confusing for you, so one duplicated line really isn't such a big problem.
As an aside, you may wish to reconsider your use of what are often considered bad practices: using namespace std; and endl. (Disclaimer - these are opinions, not hard facts).

Can someone explain a c++ while loop?

So, I'm trying to create a program that has a never ending while loop unless the user pressing a certain key to exit. Now I'm pretty sure that I need to use a while loop but I'm not 100% sure how it works. I've been trying to add error messages to. The user is suppose to enter a numbered grade and it calculates the gpa but I need to validate the user input to make sure it is numeric and between 0 and 100 but after I put the error message in the loop it just is never ending (literally it shows the message down the page over and over without me touching anything)
could someone explain?
int main()
{
int grade; // input
char y; //determines what letter to press to exit
bool validGrade = true; //determines if grade is valid
cout << "Enter percentage grades to convert to grade points. Press [y] to exit.";
cin >> y;
while(validGrade)
{
cout << "Percentage Grade: ";
cin >> grade;
if (!validGrade)
{
cout << "* Invalid input. Please try again and enter a numeric value.";
}
}
}
this is my code^
A C++ while loop,
while (condition) statement
Will repeatedly evaluate statement while condition evaluates to true.
A common issue that results in infinite loops is creating a program that never modifies condition such that it becomes false. For example, in your program, the condition is validGrade, which you've initialized to true. Do you ever modify validGrade? If not, the condition will remain true forever, and thus loop forever.
You mentioned performing checks on grade, but it seems like you haven't implemented them yet. Think about how you could modify the condition variable to ensure that the loop terminates eventually.
I'd also encourage you to read some tutorials to gain a better understanding of while loops. Here's one to start you off.
Your while loop condition has been initialized to true. So it is supposed to run indefinitely. Based on your question, I think what you're trying to do is to check input stream:
int main() {
int grade; // input
char y; //determines what letter to press to exit
bool validGrade = true; //determines if grade is valid
cout << "Enter percentage grades to convert to grade points. Press [y] to exit.";
cin >> y;
while(cin >> grade) {
cout << "Percentage Grade: ";
if (!validGrade) {
cout << "* Invalid input. Please try again and enter a numeric value.";
} } }

Using do while loop and while loop to write a program that will run random guessing game...i stuck at the do while loop

I have been run a random guessing game. The game secret numbers is from min to max that input by user, the guesser is ask guess the secret number and at the end is supposed to be asked if they would like to play again. There also has to be multiple options for print outs if the guesser is to high or low. Anyways, I want it to check and make sure that the user is inputting numbers, not something silly. So I have been going in circles trying to figure this part out. I am sure it is a easy fix, but I am new to programming and this has got me stumped. Any help would be appreciated.
my code should similar to below output images :
[1]http://i62.tinypic.com/wjvuqb.png
[2]http://i57.tinypic.com/2nq9jwm.png
[3]http://i62.tinypic.com/210zss7.png
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
int min, max, secret=0, deposit, bet, guess;
bool again= true;
string name;
char reply;
cout<< setw(80)<< setfill('=')<<"\n\n";
cout<< setw(45)<< "NUMBER GUESSING GAME!"<<"\n\n";
cout<< setfill('=')<< setw(80)<<"\n\n";
cout<< "What ur name?\n";
getline(cin,name);
Again:
cout<< "Pls enter the min & max number\n";
while(!(cin>>min)||min<0)
{
cout<<"Min? ";
cin.clear();
cin.ignore();
}
while(!(cin>>max)||max<0)
{
cout<<"Max? ";
cin.clear();
cin.ignore();
}
while(!(max> min))
{
cout<<"Min is larger than Max\n";
goto Again;
}
cout<< "\nMin: "<<min<<"\nMax: "<<max<<"\n";
secret= rand() % max+min;
cout<<"Enter ur deposit: ";
cin>> deposit;
AA: cout<< setw(45)<< "\n\n\n\nRULES OF THE GAME"<<"\n\n";
cout<< setfill('-')<< setw(80)<<"\n\n";
cout<< "Guess number between "<< min<< " to "<< max;
cout<< "\nIf ur guess match, 10 times ur deposit!!";
cout<< "\nIf ur guess mismatch, lose ur betting amount!!";
cout<< "\n\n"<< setfill('-')<< setw(80)<<"\n\n\n";
cout<< "Current Balance: "<<deposit;
cout<< "\nWhat is ur betting amount? ";
cin>> bet;
do{
cout<< "\n\nEnter a guess to bet: ";
cin >> guess;
if (guess > max)
{
cout << "Too high!\n\n";
cin.clear();
cin.ignore();
}
else if (guess < min)
{
cout << "Too low!\n\n";
cin.clear();
cin.ignore();
}
}while (guess != secret);
if(guess != secret){
deposit-=bet;
cout << "\nThat's it! You got it!\n";
cout<<"Sorry, U lose RM "<< bet;
}
else{
bet*=10;
deposit+=bet;
cout << "\nThat's it! You got it!\n";
cout<<"Congratulation! U earn RM "<< bet;
}
cout<<"\n\nThe secret number was : "<< secret;
cout<< "\n\n\tCurrent Balance: "<<deposit<< "\n\n\n";
do{
cout<< "Wanna play again (y/n)? ";
cin>> reply;
if( reply=='y'){
again= true;
goto AA;
}
else
cout<<"\nReally? Ok, try again! ";
cin>>reply;
}while(again==false && reply=='n');
if(reply=='n'){
cout<<"\n\n\n"<< setw(80)<< setfill('+')<<"\n\n";
cout<< setw(30)<< "THX FOR PLAYING! UR CURRENT BALANCE IS RM "<< deposit<<"\n\n";
cout<< setfill('+')<< setw(80)<<"\n";
}
return 0;
}
You are using goto, and if you are using goto, raptors will tear you to pieces. Do not, under any circumstances use goto!
But you can use functions to make your code a bit clearer. This wall of text and copy paste is really hard to read.
First of all the formula you are using to calculate the random number is wrong. Suppose that min is 10, and max is 12. Then the rand() % max could be, let's say, 10. Adding min (10), the number to guess would be 20 - far greater than max... It should be secret = rand() % (max-min +1) + min; (if your interval is [min, max]).
Now to your question - as far as I understood you want to know if the entered guess is a number. Here is what you can do:
while(1)
{
cin >> guess;
if(cin){
if (guess > max){
cout << "Too high!\n\n";
cin.clear();
cin.ignore();
continue;
}
else if (guess < min){
cout << "Too low!\n\n";
cin.clear();
cin.ignore();
continue;
}
else if(guess != secret){
deposit-=bet;
cout<< "Sorry, U lose RM "<< bet;
}
else if(guess == secret){
bet*=10;
deposit+=bet;
cout<< "\n\nCongratulation! U earn RM "<< bet;
}
break;
}
else
{
cin.clear();
cin.ignore();
cout << "Error! You did not enter a number!" << endl;
continue;
}
}
If the user didn't enter a number, the cin's fail flag will be up and you can use that.
Also, when trying again (goto AA;) you do not compute the random value again and you should. In order to get a different sequence of random numbers from rand() every time you start the program, you should seed the random generator from the current time. In the beginning of main, put srand((unsigned int)time(NULL)); What this does is that it gives the random generator a number and on its base it will generate random numbers. If the number is the same every time the program is started, the same numbers will be generated. But given the always changing current time, every time the sequence will be different.
Using goto can make your code very messy and can make bugs very hard to notice. Yes, it is a part of the language and it is there to be used, but one should be very careful with it. Especially if you are new to programming, try to refrain from using it. You could use while(1) or for(;;) if you need endless loops - you can get to the next iteration with continue; and stop them with break;.
Something is also wrong with the guessing loop. It seems that you cannot lose. You should decrease the deposit in the while loop and check if it is 0.
Edit: In the edited code you can see that whenever the user needs to enter the number again, you just skip the iteration with continue. This is also an example how you should deal with endless loops instead of using goto. With practice, you will get he hang of it. ;)
Edit 2:
do{
cout<< "Wanna play again (y/n)? ";
cin>> reply;
if( reply!='y'&& reply!='n')
cout<< "\nReally? Ok, try again! \n";
}while(reply!='n' && reply!='y');
if( reply =='y')
goto AA;
if(reply=='n'){
cout<< "\n\n\n"<< setw(80)<< setfill('+')<< "\n\n";
cout<< setw(30)<< "THX FOR PLAYING! UR CURRENT BALANCE IS RM "<< deposit<< "\n\n";
cout<< setfill('+')<< setw(80)<< "\n";
}
This should make the reply cycle work. Your program should consist of different chunks of code for different purposes, and in this cycle you mixed up checking the correctness of the answer with what will happen if the answer is correct. It's easier first to do the first, and then to do the second thing. Using functions can generally help you with this.
Edit 3: In that new code you have a lot of problems with if statement. Firstly, what is !> ? I think you meant < or <= , !> does not exist, it won't even compile. Another thing - what happens when max or min is 0? You haven't covered that.
You use if-else chains a lot and in this case it is not necessarily needed. For example you don't need if(min>0) , you don't even need the else before it. If you don't enter one of the if statement - the input is correct and you can break, if you enter one of them - it has continue; in it and the code below is not executed. The same goes for the last if statement in the max if-else chain executed if the input is a number.
Anyway, you could do it a lot simpler. For example the min loop can be:
cout << "Pls enter the min of secret number\n";
while (!(cin >> min) || min<=0){
cout << "Pls enter the min of secret number\n";
cin.clear();
cin.ignore();
}
You could see that this will work if you realize that you should break if (cin && min>0). Now when you negate that in order to place it as the while condition it becomes (!cin || min<=0).
Anyway, I didn't see any other problem in the code, I tested it and it worked. And now without goto it looks a lot better.