Inner while loop iteration with outer loop - c++

I have a simple nested while loop situation but I'm not sure how to increment numGuesses inside the second loop to escape the first loop once it is no longer less than 5.
while(numGuesses<5){
while(!correct){
cout << "\nGuess the number the computer randomply picked between 1 - 100: ";
numGuesses++;
cin >> guess;
if(guess<number){
cin.clear(); //clears input stream
cin.ignore(256, '\n');
cout << "\nSorry, your guess is too low";
}
else if (guess>number){
cout << "\nSorry, your guess is too high";
}
else{
cout << "\nYou guessed right, you win!";
correct = !correct;
}
}
}
cout << "Sorry, you lost. The number is: " << number;
Each time the inner while loop iterates I would like numGuesses to increase but I'm guessing its not in its scope?

You should just use one while loop! After all, the thing you're looping over is prompting for a guess. There's no need for a second layer of looping inside that. Think about when you want to stop asking for a guess -- when the guesses get to 5 or when they get it correct. So when do you want to keep asking for a guess? When the guesses are less than 5 and they have not got it correct. Also, you want to say whether they lost after the end of the loop depending on the value of correct.
while(numGuesses<5 && !correct) {
cout << "\nGuess the number the computer randomply picked between 1 - 100: ";
numGuesses++;
cin >> guess;
if(guess<number){
cin.clear(); //clears input stream
cin.ignore(256, '\n');
cout << "\nSorry, your guess is too low";
}
else if (guess>number){
cout << "\nSorry, your guess is too high";
}
else{
cout << "\nYou guessed right, you win!";
correct = !correct;
}
}
if (!correct) { // loop stopped before they got it correct
cout << "Sorry, you lost. The number is: " << number;
}
You'll also want "\n"s or std::endls at the end of your print statements, otherwise your code will print everything on one line.

You don't need 2 whiles...
while(numGuesses < 5 && !correct)
{
// your logic here
}
After that you can check either the variable correct or numGuesses. For example:
if(!correct)
// your code

Related

While loop creating infinite loop

So I'm creating a program for a C++ class, and I created a while loop to stop invalid inputs.
Every time I do test it with an invalid input it goes into an infinite loop. I'm new to coding, so I really don't know how to fix it.
cout << "Enter weight in ounces (Max: 1800)" << endl;
cin >> pkgweight;
while (pkgweight > 0 || pkgweight < 1800)
{
cout << "Weight out of range. Program terminating.\n" << endl;
}
cout << "Enter miles shipping (Max: 3500)" << endl;
cin >> distance;
while (distance > 0 || distance < 3500)
{
cout << "Shipping distance out of range." << endl;
cout << "Program terminating.\n" << endl;
}
If nothing changes inside that loop, the exit condition will never be tripped.
Maybe you mean:
int pkgweight = 0;
cout << "Enter weight in ounces (Max: 1800)" << endl;
cin >> pkgweight;
if (pkgweight < 0 || pkgweight > 1800)
{
cout << "Weight out of range. Program terminating.\n" << endl;
}
You'll want to use while for situations where you want to loop until some condition is met. if is like a non-looping while.
While it's great that you're learning and it's understood you're going to make mistakes, slipping up on something this fundamental is usually a sign you don't have a good reference to work from. Get yourself a solid C++ reference book and refer to it often if you're ever stumped about something. This is essential for learning properly, not just picking up bits and pieces here and there and trying to intuit the gaps. Many parts of C++ will not make sense, they are artifacts of design decisions decades old and the influence of other programming languages you've never heard of. You need a proper foundation.
If you want the user to be able to fix an incorrectly entered input, you would want:
cout << "Enter weight in ounces (Max: 1800)" << endl;
cin >> pkgweight;
while (pkgweight > 0 || pkgweight < 1800)
{
cout << "Weight out of range. Program terminating.\n" << endl;
cout << "Enter weight in ounces (Max: 1800)" << endl;
cin >> pkgweight;
}
That way, if the user enters a number which is outside of the valid range, they will be prompted to enter a new number. If the new value is within the range, the loop will exit.
The problem with your current program is that a while loop will execute "while" the condition it checks for is true. In your current program, once pkgweight is set, it stays the same value. This means that if the loop is entered because the condition it checks for is true, that condition will never change (allowing the loop to exit), and your error message will be printed indefinitely.
Looking at your code, it seems like you want to kill the program if the input is wrong. You could consider terminating the function. Is this all in main()? If it is not in an external function, just do return -1. I know this is probably bad programming practice, but hey, it works specifically for this!
By the way, your conditional said > 0 and < 1800, which means the program will terminate if the variables distance and pkgweight are in the specified range.
Here is my working snippet without these errors, tested on onlineGDB.
#include <iostream>
using namespace std;
int main ()
{
int pkgweight, distance;
cout << "Enter weight in ounces (Max: 1800)" << endl;
cin >> pkgweight;
while (pkgweight < 0 || pkgweight > 1800)
{
cout << "Weight out of range. Program terminating.\n" << endl;
return -1;
}
cout << "Enter miles shipping (Max: 3500)" << endl;
cin >> distance;
while (distance < 0 || distance > 3500)
{
cout << "Shipping distance out of range." << endl;
cout << "Program terminating.\n" << endl;
return -1;
}
return 0;
}
Of course, instead of switching the less-than and greater-than, you could always wrap the conditional in a not operator.

Programming Principles and Practice: chapter 4 drill part 1

I just can't seem to get this program to work properly. I can get it to accept two integers and print them to the screen. But I can't get the program to terminate when the '|' is used. Once that its entered it loops infinitely. Here is the code that I have so far:
#include "../../std_lib_facilities.h"
int main()
{
int num1 = 0;
int num2 = 0;
char counter = '\0';
cout << "Please enter two integers and press enter. \n";
bool test = true;
while (counter != '|')
{
cin >> num1 >> num2;
cout << "Your numbers are: " << num1 << " " << num2 << endl;
if (cin.fail())
{
cout << "Goodbye!\n";
test = false;
}
else (counter != '|');
cout << "Enter more numbers or press '|' to exit.\n";
}
system("pause");
}
You are using the wrong condition in your while loop. You are never changing counter so the loop will never end. However you do change test to false in the while loop if the input fails. You can change the condition of the while loop to use test instead like
while(test)
{
//...
}
Since counter is no longer being used you can get rid of it completely.
Please note that unless you change to taking in string and parsing the input any input that will cause cin to fail will end the loop not just a |.

How do I stop this from infinitely repeating, but still keep the loop?

On line 33, there is a break to stop the code from repeating indefinitely, but I would like it to take part in the while loop.
The Code:
#include <iostream>
using namespace std;
int main()
{
while (true){
{
cout << "This program counts by twos to any number that is inputted by the user." << endl;
cout << "Input an even number to start counting." << endl;
int input;
cin >> input;
if (!cin.fail())//fails if input is not an integer
{
if (input < 0)//makes sure all numbers are positive
{
cout << "That is not a positive number. Try again?" << endl;
}
else if (input % 2 != 0) // makes sure all numbers are even
{
cout << "That is not an even number. Try again?" << endl;
}
else{
for (int i = 0; i <= input; i += 2) //uses a for loop to actually do the counting once you know that the number is even.
{
cout << i << endl;
}
}
}
if (cin.fail())//returns this when you input anything other than an integer.
{
cout << "That is not a digit, try again." << endl;
break;
}
}
}
return 0;
}
If you guys could help me find why this repeats, that would really help.
You need to add a break statement after the for loop in order to exit the loop. Without the break the for loop will execute and print your output and then control will fall to the end of the while loop where it will start back at the top of the loop.
I would also suggest changing if (cin.fail()) to just else as you are already checking if (!cin.fail()). You also need to ignore the rest of the input and clear the error flags if you want to loop again.
You also had a extra set of brackets in the while loop. With those changes your code would be:
#include <iostream>
#include <limits>
using namespace std;
int main()
{
while (true)
{
cout << "This program counts by twos to any number that is inputted by the user." << endl;
cout << "Input an even number to start counting." << endl;
int input;
cin >> input;
if (!cin.fail())//fails if input is not an integer
{
if (input < 0)//makes sure all numbers are positive
{
cout << "That is not a positive number. Try again?" << endl;
}
else if (input % 2 != 0) // makes sure all numbers are even
{
cout << "That is not an even number. Try again?" << endl;
}
else{
for (int i = 0; i <= input; i += 2) //uses a for loop to actually do the counting once you know that the number is even.
{
cout << i << endl;
}
break; // exit the while loop
}
}
else //else when you input anything other than an integer.
{
cout << "That is not a digit, try again." << endl;
cin.clear(); // reset the error flags
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // clear any extra input
}
}
return 0;
}
Based on the error message you print, I'm guessing your problem is that you want to give the user a chance to try again to enter a number, but after one failure, it continuously fails no matter what you enter. If that's the case, replace your break with cin.clear(). That will tell the stream that you've recovered from the error and are ready to receive more input.
If you're going to do that, though, your program now has no exit condition, so you'll want to add a break (or return 0) just after the for-loop.

Whites space being read into the rear of string using getline()

Look, i have been writing this guessing game for a day and a half now. I keep getting errors related to using cin and getline together, and using a lot of advice I received from Stackoverflow, I thought I fixed all the bugs. Also, I realize it's best not to use >> and getline together, but to be honest, I don't know any other way, and I am afraid I will lose points if I use features of the language that our professor hasn't specifically taught us. So please just help me out, I have been ocd-ing like a maniac.
The game works correctly, and the game repeats, (I also know that using goto is evil, but this is just a very basic guessing game. I pinky promise not to ever use it in real life)
The problem arises when the game repeats a second time. After the game prompts the user to enter Y to continue, and they do, it will goto the start of my do-while loop, as it should. Stack unwinding be damned.
Next, it will read in the user input, ignoring white space at the stare of cin. But somehow, white space hops in at the end of my word after a few runs? I am baffled by this, as I thought that my loop which tests each index using the isalpha function would prevent this?
I could really use some concrete code to fix this, I have been up all night. Suggestions are fine but I don;t fully understand them and I am not allowed to use a good chunk of this languages features. Yes, I realize that is ridiculous, but I'm not my professor.
Here is a screenshot of the logical error:
Here is my code so far: You can read some of my comments to see the different paths this beast has been down:
#include<iostream>
#include<string>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <ctype.h>
using namespace std;
int main() {
string secretWord;
string secretWordClean = "";
string guessedLetters; //to be loaded with _ characters equal to length of secretWord
string incorrectlyGuessedChars = "";
char individualCharGuess;
char playAgain;
size_t countOfLetters = 0; //begine count at 0
size_t guessesRemaining;
int guessedUsed;
begin_game://label which we can use to bring us back to the start of the do-while loop at any time
//do{//start of the game
cout << "Please enter a secret word: ";
std::cin >> std::ws;
getline(std::cin, secretWord);
secretWord.erase(std::remove_if(secretWord.begin(), secretWord.end(), std::not1(std::ptr_fun(isalnum))), secretWord.end());
//std::cout << secretWord << "\n";
for(int i = 0; i < secretWord.length(); i++){
if (isalpha(secretWord[i])){
secretWordClean += secretWord[i];
}
}
secretWord = secretWordClean; //assign all alpha secret word string back to original variable for better readability
guessesRemaining = secretWord.length() * 2;
//cout << "Please enter a secret word: ";
//cin >> secretWord;
do{//start of the guessing portion of game
for(int i = 0; i < secretWord.length(); i++){
guessedLetters += "_"; //fills guessedLetters with blanks equal to the length of the secretWord
}
cout << "Please guess a letter, you have " << guessesRemaining << " guesses remaining!" << endl;
cin >> individualCharGuess;
for(int i = 0; i < secretWord.length(); i++){ //every complete iteration of this for loop = one single guess
if(secretWord[i] == individualCharGuess){
guessedLetters[i] = individualCharGuess; //will replace the spaces with the correct character, if guessed
countOfLetters++; //if any letter is guessed correctly, this indicator will be incrimented above 0
continue;
}
if(secretWord.find(individualCharGuess) == string::npos){
if(incorrectlyGuessedChars.find(individualCharGuess) == string::npos){
incorrectlyGuessedChars += individualCharGuess;
}
}
}
if(secretWord.compare(guessedLetters) == 0){
cout << "You win! The word was: " << secretWord << endl;
guessedUsed = ((secretWord.length() * 2) - guessesRemaining) + 1 ;
cout << "You used " << guessedUsed << " guesses." << endl;
cout << "Play again? Enter Y for Yes, or anything else to exit: ";
cin >> playAgain;
if(playAgain != 'Y'){
break; //exit the loop if user guesses all the letters and doesn't want to play again
}
else {
incorrectlyGuessedChars = "";
secretWordClean = "";
//continue;
goto begin_game;
}
}
guessesRemaining--; //we decriment our total guesses remaining if the user does not win the game or run out of guesses
if(countOfLetters > 0){
cout << "You have correctly guessed a letter!" << endl;
cout << "Here are the letters you have guessed correctly so far: ";
cout << guessedLetters << endl;
cout << "Here are the letters you have guessed incorrectly so far: ";
cout << incorrectlyGuessedChars << endl;
countOfLetters = 0; //reset the counter to prepare for next iteration of do-while loop
}
else if (guessesRemaining <= 0) {
cout << "You have run out of guesses!" << endl;
cout << "Here are the letters that you guessed correctly: ";
cout << guessedLetters << endl;
cout << "Here are the letters you guessed incorrectly: ";
cout << incorrectlyGuessedChars << endl;
cout << "The secret word was: " << secretWord << endl;
cout << "Play again? Enter Y for Yes, or anything else to exit: ";
cin >> playAgain;
if(playAgain != 'Y'){
break; //exit the loop if user guesses all the letters and doesn't want to play again
}
else {
secretWordClean = "";
incorrectlyGuessedChars = "";
//continue;
goto begin_game;
}
}
else {
cout << "You guessed wrong! Keep trying, " << guessesRemaining << " guesses to go!" << endl;
cout << "Here are the letters you have guessed correctly so far: ";
cout << guessedLetters << endl;
cout << "Here are the letters you have guessed incorrectly so far: ";
cout << incorrectlyGuessedChars << endl;
}
}while (secretWord.compare(guessedLetters) != 0 || guessesRemaining != 0); //use to repeat the request for a single char guess
return 0;
}
You should initialize with blanks (the _ character) the string before the loop starts, not at the beginning of every iteration, change your code to:
for (int i = 0; i < secretWord.length(); i++) {
guessedLetters += "_"; //fills guessedLetters with blanks equal to the length of the secretWord
}
do{ //start of the guessing portion of game
... rest of the code ...
if you don't, at every iteration of your game the guessedLetters variable is going to have more _ characters appended at the end of it, spoiling your final string comparison.
You should also clear the guessedLetters if you plan to play again:
else {
incorrectlyGuessedChars = "";
secretWordClean = "";
guessedLetters = ""; // Cleanup
//continue;
goto begin_game;
}
as a sidenote: gotos are a terrible programming practice and can render the code very unreadable/unmaintainable. I suggest redesigning your application without using gotos in a future revision.

How could I exit from do-while loop?

I have these block of codes that belong to a NIM subtraction game. The thing that I would like to implement is that user is going to be able play the game as long as he/she wants. Simply if user enters 999 program will exit, otherwise user will be playing until he/she enters 999. Here is my block of codes. I am not sure that I make a logical mistake or I need to add some specific exit code. Thanks for your time and attention.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int total, n;
while(true){
cout << "Welcome to NIM. \nEnter 999 to quit the game!\nPick a starting total: ";
cin >> total;
if(total==999)
break;
while(true){
//pick best response and print results.
if ((total % 3) == 2)
{
total = total - 2;
cout << "I am subtracting 2." << endl;
}
else
{
total--;
cout << "I am subtracting 1." << endl;
}
cout << "New total is " << total << endl;
if (total == 0)
{
cout << "I win!" << endl;
break;
}
// Get user’s response; must be 1 or 2.
cout << "Enter num to subtract (1 or 2): ";
cin >> n;
while (n < 1 || n > 2)
{
cout << "Input must be 1 or 2." << endl;
cout << "Re-enter: ";
cin >> n;
}
total = total - n;
cout << "New total is " << total << endl;
if (total == 0)
{
cout << "You win!" << endl;
break;
}
}
}
return 0;
}
You are modifying total inside the loop. Just test after cin>>total at the beginning if total==999 and break if true, i.e.
if(total==999)
break;
and replace the do-while loop by a while(true){}
In the do-while loop you are trying to compare character literal '999' with variable total that has type int.
}while(total!='999');
Though this code is valid its result can be something else than you are expecting. Values of character literals with more than one symbol are implementation defined.
You have to write
} while ( total != 999 );
Also if the player will enter 999 you start to play with him though you have to exit the game.
So in my opinion it is better to use while loop. For example
while ( true )
{
cout << "Welcome to NIM. \nEnter 999 to quit the game!\nPick a starting total: ";
cin >> total;
if ( total == 999 ) break;
// ...
}
you have to do three corrections in your code to make it right
first you have to check if total is equal to 999, then break in your do loop just after getting the total from user
second - you have to put same condition in your first while loop
and lastly - instead of while(total!='999') u shall write while(total!=999) because it is integer