I Can't Figure Out Why This Loop Is Malfunctioning - c++

So I just can't figure out what's wrong with my code. When I process a purchase, after I enter the amount of yogurt and am told to go enjoy it, I immediately after get the error message I made for if people don't input P or S, then right afterwards it goes back to normal like it is when you first enter the program, could anybody tell me why this is? Thank you!
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string userCommand;
int creditCount = 0;
int userInput;
while (creditCount >= 0)
{
cout << "--------Menu--------\n" << "P (Process Purchase)\n" << "S (Shutdown System)\n"
<< "--------Menu--------\n" << "Your Choice: ";
getline(cin, userCommand);
if (userCommand[0] == 'P' || userCommand[0] == 'p')
{
if (creditCount >= 10)
{
cout << "You qualify for a free yogurt, would you like to use ten of your credits (Yes or No)?";
getline(cin, userCommand);
if (userCommand[0] == 'Y' || userCommand[0] == 'y')
{
creditCount = creditCount - 10;
cout << "You just used 10 credits and now have " << creditCount << " left.\n"
<< "Enjoy your free yogurt!";
}
else if (userCommand[0] == 'N' || userCommand[0] == 'n')
{
cout << "How many yogurts would you like to buy? ";
cin >> userInput;
if (userInput > 0)
{
creditCount = creditCount + userInput;
cout << "You just earned " << userInput << " stamps. You now have " << creditCount
<< " credits! Enjoy your yogurt!";
}
else
{
cout << "Invalid input, please try processing your purchase again and enter a positive "
<< "integer.";
}
}
else
{
cout << "*Error, please try processing your purchase again and enter either Yes or No*\n\n";
}
}
else if (creditCount < 10)
{
cout << "How many yogurts would you like to buy? ";
cin >> userInput;
if (userInput > 0)
{
creditCount = creditCount + userInput;
cout << "You just earned " << userInput << " stamps. You now have " << creditCount
<< " credits! Enjoy your yogurt!\n\n";
}
else
{
cout << "Invalid input, please try processing your purchase again and enter a positive "
<< "integer.";
}
}
}
else if (userCommand[0] == 'S' || userCommand[0] == 's')
{
cout << "*Shutting down system*\n";
return 0;
}
else
{
cout << "*Error, please enter either P (for Process Purchase) or S (for Shutdown System)*\n\n";
}
}
}

#acid1789 has pointed out correctly the error is due to the empty line after getline. From your code what i can make out is you are using an infinite loop here
while(creditCount >= 0){...}
since creditCount is never going to be less than 0 instead of this you can use
while (true){...}
its just better programming practice.
And to correct your program you can just use
cin >> userCommand;
instead of
getline(cin, userCommand);
Hope it helps.
Edit:- Sorry Python habits..

The issue here is that getline is returning an empty line.
So after your first time through the loop, it goes back to the top to read another line. Gets an empty line, which triggers the error case.
You could fix this by testing for an empty line after getline.

Related

Can't figure out how to give user all the options for starting, stopping, and restarting program?

Ok so I am trying to build this random number teller which basically tells the users whether the number they input is less than, greater than, or equal to 50 and also give them the options to start, stop, and restart the "random number teller" Here is the code:
#include <iostream>
using namespace std;
main() {
cin >> boolalpha;
int invalid_answer {0};
const int const_num {50};
int random_num {};
char answer {};
int keep_going {};
while (keep_going == 0) {
while (invalid_answer == 0) {
//=======================================================================================================================================
cout << "Enter a random number and we will tell you if it is greater than or less than " << const_num << ": " << endl;
cin >> random_num;
if (random_num > const_num) {
cout << random_num << " is greater than " << const_num;
}
else if (random_num == const_num) {
cout << random_num << " is the same as " << const_num << endl;
}
else {
cout << random_num << " is less than " << const_num << endl;
}
cout << "Want to try again? Type \"Y\" or \"N\"";
cin >> answer;
//=======================================================================================================================================
if (answer == 'N') {
cout << "Ok then, sorry to see you miss out" << endl;
keep_going = 1;
}
//=======================================================================================================================================
while(answer == 'Y') {
cout << "Enter a random number and we will tell you if it is greater than or less than " << const_num << ": " << endl;
cin >> random_num;
if (random_num > const_num) {
cout << random_num << " is greater than " << const_num;
}
else if (random_num == const_num) {
cout << random_num << " is the same as " << const_num << endl;
}
else {
cout << random_num << " is less than " << const_num << endl;
}
cout << "\nWant to try again? Type \"Y\" or \"N\"";
cin >> answer;
}
//=======================================================================================================================================
if (answer != 'Y' || answer != 'N') {
invalid_answer = 1;
}
//=======================================================================================================================================
while (invalid_answer == 1) {
cout << "I'm sorry what? Please note that answers are case sensitive. Answer again: ";
cin >> answer;
if (answer == 'Y') {
invalid_answer = 0;
}
else if (answer == 'N') {
cout << "Ok then, sorry to see you miss out" << endl;
keep_going = 1;
}
}
}
}
}
Whenever I say "N" for No I don't want to redo the random number checker, it doesn't change keep_going to 1 it just moves on to one of the other if or while statements below it. So when you input "N" it just outputs either "Enter a random number and we will tell you if it is greater than or less than " << const_num << ": " or "I'm sorry what? Please note that answers are case sensitive. Answer again: "
The problem is with this bit of code:
if (answer != 'Y' || answer != 'N') {
invalid_answer = 1;
}
When answer is 'N', answer != 'Y' is true and invalid_answer is set to 1 (because of short-circuit evaluation the rhs of the logical OR is not even evaluated - see quote below).
So the execution will enter the while
while (invalid_answer == 1)
and will print the statements.
You can correct this by:
if (answer == 'Y' || answer == 'N') { //if input is either 'Y' or 'N'
invalid_answer = 0;
}
else { //for all other inputs
invalid_answer = 1;
}
Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands
Also note that main should have the type int.
I figured it out right after I posted the question haha, basically the answer above was correct so I had to split that if statement into 2 others, in which I added an else statement to each also that said invalid_answer = 0; to make sure. But then after the user's second time using the program, if they wanted to quit it wouldn't let them and would just restart it again. I solved that by adding
if (answer == 'N') {
cout << "Ok then, sorry to see you miss out" << endl;
keep_going = 1;
}`
to the bottom of the while(answer == 'Y') loop.

Still being prompted after entering a valid input value

I made this for an assignment but even if I enter a valid input from the desired range I still get prompted. This is happening to both input prompts. I suspect the problem is in the while blocks of the setupGame function.
#include <iostream>
using namespace std;
bool setupGame(int numberRef, int triesRef);
int main(){
cout<<"hello world";
setupGame(4,4);
cout<<"enough";
}
//SETUP GAME FUNCTION
bool setupGame(int numberRef, int triesRef) {
do {
cout << "ENTER A NUMBER BETWEEN 1 and 100" << endl;
cin >> numberRef;
cin.clear();
//your code here
cout << "You entered: " << numberRef << endl;
if (numberRef==-1) {
cout << "You do not want to set a number " << endl;
cout << "so you stopped the program" << endl;
}
else if(numberRef >=1 && numberRef <=100)
do {
cout << "ENTER TRIES BETWEEN 3 and 7" << endl;
cin >> triesRef;
cin.clear();
//cin.ignore( '\n');
cout<< "You entered: "<< triesRef<< endl;
if (triesRef==-1) {
cout << "You do not want to set tries. ";
cout << "so you stopped the program" << endl;
} else if(triesRef <= 3 && triesRef >= 7){
cout<<"Number of tries should be between 3 and 7";
}
}
while(numberRef >=1 && numberRef <=100);{
return true;
}
}
while(triesRef >= 3 && triesRef <= 7);{
return true;
} }
You're tangling yourself up with these nested loops. Your prompt keeps printing because the while loop:
while(numberRef >=1 && numberRef <=100)
is going to keep repeating it's preceding do block until you enter a value less than 1 or greater than 100, same goes for the last while loop as well.
I assume you're using cin.clear() to flush the previous input, if you are then stop it, that is not the purpose of cin.clear(). It's instead use to clear the error state of cin. Please thoroughly read up on it here.
Below is the code to achieve what you want, please observe how I implemented the while loops after each cin prompt to ensure that a valid character is entered.
#include <iostream>
#include <fstream>
using namespace std;
bool setupGame(int numberRef, int triesRef);
int main(){
cout<<"hello world";
setupGame(4,4);
cout<<"enough";
}
//SETUP GAME FUNCTION
bool setupGame(int numberRef, int triesRef) {
cout << "ENTER A NUMBER BETWEEN 1 and 100" << endl;
cin >> numberRef;
while((numberRef < 1 || numberRef > 100 || cin.fail()) && numberRef != -1) {
cin.clear(); // Used to clear error state of cin
cin.ignore(); // Might want to ignore the whole line
cout<<"Number should be between 1 and 100, or -1 , please try again: ";
cin>>numberRef;
}
cout << "You entered: " << numberRef << endl;
if (numberRef==-1) {
cout << "You do not want to set a number " << endl;
cout << "so you stopped the program" << endl;
}
if(numberRef >=1 && numberRef <=100) {
cout << "ENTER TRIES BETWEEN 3 and 7" << endl;
cin >> triesRef;
while(triesRef < 3 || triesRef > 7 || cin.fail()) {
cin.clear(); // Used to clear error state of cin
cin.ignore(); // Might want to ignore the whole line
cout<<"Tries should be between 3 and 7 , please try again: ";
cin>>triesRef;
}
cout<< "You entered: "<< triesRef<< endl;
if (triesRef==-1) {
cout << "You do not want to set tries. ";
cout << "so you stopped the program" << endl;
return false;
}
}
}

how to accept only whole numbers in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am new to programming and I need help with my term project. I have made a program that simulates a hotel booking, the problem is that whenever a non-whole number is entered for the first question, it goes into an infinite loop. If you get to the second question and enter a non-whole number it accepts it as a whole number by dropping off anything that comes after the decimal and then skips the next question and stops running the program.
#include <iostream>
#include <string>
using namespace std;
int stay_length (int stay)
{
int nights = stay;
int total = 0*nights;
return total;
}
int rooms_booking(int rooms)
{
int rooms_booked = rooms;
int total = 0;
if(rooms_booked > 0)
{
total = rooms_booked * 50;
}
else
{
total = 0;
}
return total;
}
int main(){
int x;
string repeat;
int nights;
int total = 0;
int rooms_avail = 10;
int rooms;
cout << "Hello! Welcome to Hotel COMP 150." << endl;
do {
if (rooms_avail > 0) {
cout << "How many nights will you be staying?" << endl;
}
else {
cout << "Sorry, but there are no rooms available. " << endl;
}
do {
cin >> nights;
if (nights > 0 && nights <= 28)
{
int total1 = stay_length(nights);
cout << "You are staying for " << nights << " nights" << endl;
cout << "That costs: $" << total1 << endl;
total = total + total1;
}
else
{
cout << "You cannot stay less than 1 or more than 28 nights" << endl;
}
} while (nights <= 0 || nights >28);
if (rooms_avail > 0)
{
cout << "How many rooms will you be booking?" << endl;
cout << "There are " << rooms_avail << " available." << endl;
cin >> rooms;
if (rooms > 0 && rooms <= rooms_avail)
{
int total2 = rooms_booking(rooms);
cout << "You are booking " << rooms << " rooms." << endl;
cout << "That costs : $" << total2 << endl;
total = total + total2;
rooms_avail = rooms_avail - rooms;
}
else if (rooms <= 0 || rooms > rooms_avail)
{
do{
cout << "You can only book a minimum of 1 room or a maximum of " << rooms_avail << endl;
cin >> rooms;
} while (rooms <= 0 || rooms > rooms_avail );
int total2 = rooms_booking(rooms);
cout << "You are booking " << rooms << " rooms." << endl;
cout << "That costs : $" << total2 << endl;
total = total + total2;
rooms_avail = rooms_avail - rooms;
}
else
{
cout << "You cannot book more than " << rooms_avail << endl;
}
}
else
{
cout << "Sorry, all rooms have been booked." << endl;
}
cout << "Your total so far is: $" << total << endl;
cout << "Would you like to make another booking? Enter 'Y' or 'y' to do so." << endl;
cin >> repeat;
}while(repeat == "Y" || repeat == "y");
return 0;
}
It's always better to use std::getline() instead of operator>> to read interactive input from std::cin.
operator>> is not for reading a single line of text from standard input, and storing it. That's what std::getline() is for.
If the wrong kind of input is entered, not what operator>> expects, it sets std::cin to a failed state, which makes all future attempts to read std::cin immediately fail, resulting in the infinite loop you are observing.
To do this correctly, it is going to be either:
1) Always check fail() after every operator>>, to see if the input failed, if so recover from the error with clear(), then ignore(). This gets real old, very quickly.
2) It's much easier to read a single line of text with std::getline(), then parse the input yourself. Construct a std::istringstream, if you wish, and use operator>> with that, if that makes it easier for you.
You can achieve basic user-input error checking via the console with something along these lines:
int nights = 0;
// error checking loop
while(1) {
std::cout << "How many nights will you be staying?" << endl;
std::cin >> nights;
// input valid
if(!std::cin.fail() && (std::cin.peek() == EOF || std::cin.peek() == '\n')
&& nights > 0 && nights <= 28) {
// do stuff
break; // break from while loop
}
// input invalid
else {
std::cin.clear();
std::cin.ignore(256, '\n');
std::cout << "An input error occurred." << std::endl;
}
}

C++ exit loop not working

well its a simple project it does everything as it should minus it wont exit when it is suppose to.
I have tried many different ways including goto statements I tried a if loop but got nothing but errors. The current code gives no errors just I dont know where to go to make it exit. It doesnt have to be fancy this is only my second program
// C// Guess My Number
// The classic number guessing game
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0))); //seed random number generator
int secretNumberE = rand() % 10 + 1;
int secretNumberM = rand() % 100 + 1;// random number between 1 and 100
int secretNumberH = rand() % 1000 + 1;
int tries = 0;
int guess;
char play;
{
cout << "\tWelcome to Guess My Number\n\n";
START:
cout << "Difficulty Levels\n\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n\n";
int choice;
cout << "Choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "You picked Easy.\n";
do
{
cout << "Enter a guess 1-10: ";
cin >> guess;
++tries;
if (guess > secretNumberE)
{
cout << "Too high!\n\n";
}
else if (guess < secretNumberE)
{
cout << "Too low!\n\n";
}
else
{
cout << "\nThat's it! You got it in " << tries << " guesses!\n";
}
} while (guess != secretNumberE);
std::cout << "Do you want to play again y/n? ";
cin >> play;
if ( play = 'y' ){
goto START;
}
else if (play = 'n')
{
cout << " Thank you for playing. ";
return 0;
}
break;
case 2:
cout << "You picked Normal.\n";
do
{
cout << "Enter a guess 1-100: ";
cin >> guess;
++tries;
if (guess > secretNumberM)
{
cout << "Too high!\n\n";
}
else if (guess < secretNumberM)
{
cout << "Too low!\n\n";
}
else
{
cout << "\nThat's it! You got it in " << tries << " guesses!\n";
}
} while (guess != secretNumberM);
std::cout << "Do you want to play again y/n? ";
cin >> play;
if ( play = 'y' ){
goto START;
}
else if (play = 'n')
{
cout << " Thank you for playing. ";
return 0;
}
break;
case 3:
cout << "You picked Hard.\n";
do
{
cout << "Enter a guess 1-10: ";
cin >> guess;
++tries;
if (guess > secretNumberH)
{
cout << "Too high!\n\n";
}
else if (guess < secretNumberH)
{
cout << "Too low!\n\n";
}
else
{
cout << "\nThat's it! You got it in " << tries << " guesses!\n";
}
} while (guess != secretNumberH);
std::cout << "Do you want to play again y/n? ";
cin >> play;
if ( play = 'y' ){
goto START;
}
else if (play = 'n')
{
cout << " Thank you for playing. ";
return 0;
}
break;
default:
cout << "You made an illegal choice.\n";
goto START;
return 0;
}}}
if ( play = 'y' ){
goto START;
}
else if (play = 'n')
{
cout << " Thank you for playing. ";
return 0;
}
The first if will always be true, because you are using the assignment operator rather than the equality operator. You need to use == to compare two values.
...
char play;
{
...
There seems to be an extra { in your code that you are wrapping your stuff with.
Things that are clear to me that you need to work on, indentation. There is probably an auto-format shortcut in your IDE. Start using that. It's impossible to read your code well this will lead to a bunch of errors in the long run for simple things that you will be banging your head over.
goto highly recommend not using this unless you know what your doing.
Start learning functions/methods they will save your life and overall improve you workflow.
and you can replace goto with it.
example of a function..
int startGame(){
cout << "Difficulty Levels\n\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n\n";
int choice = 0;
cout << "Choice: ";
cin >> choice;
return choice;
}
Other things.
if ( play = 'y' ) needs to be if ( play == 'y' ) rinse repeat this because you are trying to check for equality(conditional) not setting a value which is what one = does.
Also, ALWAYS INITIALIZE VALUES int choice; should be int choice = 0; or some default value.
use the "break" keywork
do
{
if(mycondition)
{
break;
}
} while (loopCondition);

Input errors in c++ program

when press "1" to start the game a error message comes up first instead of playing the game and then I have to enter "1" 3 times before the game starts and also the quit game option only works when you select "2" first if its not selected first it just comes up as a error message I cant see why it does this can anyone help me please ?
#include "Questions.h"
#include <iostream>
using namespace std;
const int MAXITEMS = 10;
int main ()
{
string question[MAXITEMS] = {"How man cards in a suit",
"How_many_suits_are_there_in_a_standard_pack_of_card",
"How_many_kings_are_in_a_standard_pack_of_cards"};
string answers[MAXITEMS] = {"4", "5", "6"};
int userInput = 0;
int tries = 0;
bool isGameOver = false;
cout << "select 1 to start game" << endl; //gives option to start and quit game
cout << "select 2 to quit game" << endl;
cin >> userInput;
if (userInput == 2)
{
isGameOver = true;
return 0;
};
// when game starts gives option to select question and shows all questions
do
{
if (userInput != 1||2)
{
cout << " Your input is not valid! please try again:" << endl;
// try switch cases for the different outcomes
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
cin >> userInput;
while (!(cin >> userInput))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n'); // discard the row
cout << "Your input is not valid! please try again: ";
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
}
cout << userInput << endl;
}
// reprisent all characters as number to stop while roblem
if(userInput == 1)
{
do
{
cout << "select question" << endl;
for(int i = 0; i != MAXITEMS; i++)
{
cout << i << " " << question[i] << endl;
}
int selectQestion;
cin >> selectQestion;
if(selectQestion == 0||1||2 && tries != 2)
{
cout << "Enter your answer" << endl;
string userAnswer;
cin >> userAnswer;
while (!(cin >> userAnswer))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n');
// discard the row
cout << "Your input is not valid!
please try again: ";
}
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else{
cout << "incorrect try again" << endl;
tries++;
cin >> userAnswer;
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else
cout << "Incorrect" << endl;
}
}
if (selectQestion == 0 ||1 ||2 && tries == 2)
{
cout << "you can no longer answer this question" << endl;
cout << "try another question" << endl;
}
}
while(userInput == 1);
}
}
while(isGameOver == false);
}
// add stuct or class to handle questions,
if (userInput != 1||2) doesn't do what you think. With the proper paretheses inserted, it is
if ((userInput != 1) || 2)
and 2 is nonzero, hence the condition is always true.
You want
if (userInput != 1 && userInput != 2)
The problem lies here:
if (UserInput!=1||2)
In this line, there are two conditions:
UserInput!=1 , 2
Here , whether user input is 1/2, the second condition 2 is always evaluated as true, which runs the if block
So change it to
if (UserInput!=1 && UserInput!=2)