Program Infinitely Looping - c++

This is a snippet of the code from my program. The function getMenuChoice() runs successfully on Visual Studio when I enter integers but when I enter a character it goes into an infinite loop. I was told that my program does not have to account for the user entering a character but yet when I submit it, the grading machine tells me it "exceeded the allowed length". Besides the fact it does not account for characters, I am not sure what is wrong with the function. If I was to account for characters though, how would I do that?
// Calls header and menu.
int main() {
printHeading();
getMenuChoice();
}
//Prints the header.
void printHeading() {
cout << "*******************************" << endl
<< " Birthday Calculator " << endl
<< "*******************************" << endl << endl;
}
//Prints the closer.
void printCloser() {
cout << endl;
cout << "****************************************************" << endl
<< " Thanks for using the Birthday Calculator " << endl
<< "****************************************************" << endl
<< endl;
}
void printMenu() {
cout << endl << endl;
cout << "Menu Options" << endl
<< "------------" << endl;
cout << "1) Determine day of birth" << endl;
cout << "2) Print the next 10 leap years" << endl;
cout << "3) Determine birthdays for the next 10 years" << endl;
cout << "4) Finished" << endl << endl;
cout << "Choice --> ";
}
//Gets user's menu choice.
int getMenuChoice() {
int choice;
printMenu();
cin >> choice;
//If user does not select 4, it selects their menu choice.
while (choice != 4) {
if (choice == 1) {
determineDayOfBirth();
}
else if (choice == 2) {
print10LeapYears();
}
else if (choice == 3) {
print10Birthdays();
}
//User did not enter a valid choice and the following prints.
else {
cout << "Invalid menu choice" << endl;
}
//Allows the user to enter another choice
//after they have executed one choice.
printMenu();
cin >> choice;
}
//Prints closer when user chooses 4.
printCloser();
return 0;
}

Its been awhile since I played with C++ but here is a shot.
int choice;
printMenu();
cin >> choice;
ValidateOption(choice);
// Then if you want them to be able to pick again you can just do it over again
printMenu();
cin >> choice;
ValidateOption(choice);
function ValidateOption(int choice){
//If user does not select 4, it selects their menu choice.
while (choice != 4) {
if (choice == 1) {
determineDayOfBirth();
}
else if (choice == 2) {
print10LeapYears();
}
else if (choice == 3) {
print10Birthdays();
}
//Prints closer when user chooses 4.
else if (choice == 4){
printCloser();
return 0;
}
//User did not enter a valid choice and the following prints.
else {
cout << "Invalid menu choice" << endl;
// Make the user select again because the input was invalid
printMenu();
cin >> choice;
}
}
}

You can try to flush cin like this:
cin >> choice;
cin.clear();
cin.ignore(INT_MAX);
or as suggested by #user4581301
cin.ignore(numeric_limits<streamsize>::max(), '\n');

Related

How can I return user to original switch menu from do-while loop?

how can I get user to go back to original switch menu once the user selects N at the end. When user selects N, would I use another loop to get them back to original menu? Any help is greatly appreciated.
cout << "Total Chips: " << chips << endl;
cout << "1) xxxxx" << endl;
cout << "2) xxx" << endl;
cout << "Please enter an option" << endl;
int option;
cin >> option;
switch(option)
{
case 1:
{
char again;
do
{
/* code
*/
cout << "Would you like to play again? Y/N" << endl;
cin >> again;
}while(towlower(again) == 'y'); // I'm not sure whether to use another do-while loop.
When user selects N, would I use another loop to get them back to original menu?
Yes, one that is put around the original menu, eg:
bool keepRunning = true;
do {
cout << "Total Chips: " << chips << endl;
cout << "1) xxxxx" << endl;
cout << "2) xxx" << endl;
cout << "Please enter an option" << endl;
int option;
cin >> option;
switch (option)
{
case 1:
{
char again;
do
{
/* code
*/
cout << "Would you like to play again? Y/N" << endl;
cin >> again;
}
while (again == 'y' || again == 'Y');
break;
}
...
}
}
while (keepRunning);

How to make seperate menus that work based on the login

So for the program I am making, I wanted to make a login that goes to two different menus then go back to the login. I'm not sure how to approach it now.
It goes something like:
string User;
string Pass;
int Option;
void Login(){
cout << "Enter your username: ";
cin >> User;
cout << "Enter your password: ";
cin >> Pass;
}
void Admin(){
system("CLS");
cout << "Welcome Admin" << endl;
cout << "------------" << endl;
cout << "1. Do something" << endl;
cout << "2. Do something else" << endl;
cout << "3. Log out" << endl;
cout << "4. Quit Program" endl;
cin >> Option;
}
void User(){
system("CLS");
cout << "Welcome User" << endl;
cout << "------------" << endl;
cout << "1. Do another thing" << endl;
cout << "2. Do something other things don't do" << endl;
cout << "3. Log out" << endl;
cout << "4. Quit Program" endl;
cin >> Option;
}
int main(){
Login();
if(User == "admin" && Pass == "admin"){
Admin();
if(Option == 3){
// What should I add here if would want to return to login then to user menu
}
}
else
User();
}
Well, if you want to return to login menu you can use a loop:
int main()
{
while(1)
{
Login();
if(User == "admin" && Pass == "admin")
{
Admin();
}
else
{
User();
}
if(Option == 3) continue;
if(Option == 4) break;
}
return 0;
}
upd: sorry, forgot about the loop :)

Function call not working, but console still allowing input.

The menu pops up at first which shows a list of items a user can buy. Then the user is asked whether they want to checkout their items or continue shopping. When the user types "no" after being prompted, instead of menu(); being called to bring them back to the menu. Nothing happens. I'm able to type in the console but nothing else shows up.
Here is the code for the question which is in a different function:
cout << "Would you like to checkout?" << endl;
cout << "Type 'yes' to continue or 'no' to keep shopping." << endl;
cin >> answer;
if (answer == "yes") {
checkout(mpadNum, mouseNum, hsetNum, keyboardNum, laptopNum, pcNum);
}
else if (answer == "no") {
menu(mpadNum, mouseNum, hsetNum, keyboardNum, laptopNum, pcNum);
}
Here is the code for part of the menu function if needed:
void menu(int mpadNum, int mouseNum, int hsetNum, int keyboardNum, int laptopNum, int pcNum) {
int *mpadQty;
string answer;
string option;
if (file.is_open()) {
cout << file.rdbuf();
}
cout << " " << endl;
cout << "What would you like to purchase?" << endl;
cout << "Please type your selection." << endl;
cin >> option;
if (option == "mousepad") {
cout << "How many mousepads would you like?" << endl;
cin >> mpadNum;
}
mpadQty = new int(mpadNum);
mpadAmnt += *mpadQty;
cout << "Your selection has been added to the cart" << endl;
cout << "Type anything to continue." << endl;
cin >> answer;
cart(mpadNum, mouseNum, hsetNum, keyboardNum, laptopNum, pcNum);
}
Here is a debugging hint. Try printing out the answer after your line cin >> answer.
cout << "answer->" << answer << "<-" << endl;

using getline() to input strings into the program is causing some kind of overflow into the next input [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 5 years ago.
Improve this question
I am having a number of problems in my program that all have to do with input.
The first thing in the program I ask the user to input is their name which I do so with this
cout << "Please tell me your name." << endl;
getline(cin, user_name);
cout << "Hello " << user_name << " and welcome to Fantasy Battle!" << endl;
where user_name is declared as a string variable elsewhere. This part seems to have no problems as the following message displays to the screen correctly
The next input from the user comes from this code
{
cout << "Hello, what would you like to do?" << endl;
cout << "1. Play" << endl << "2. Exit" << endl;
cout << "Please enter the number corresponding to your choice from the list
above." << endl;
for(;;)
{
if(cin >> menuChoice)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(10000, '\n');
}
if(menuChoice == 1 || menuChoice == 2)
break;
else
{
cout << "You did not enter a valid menu option. Please try
again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
else
{
cout << "You did not enter a valid menu option. Please try again."
<< endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
if(menuChoice == 2)
{
return 2;
}
else
{
//setup a fight code further down
}
One the first run through if I enter 2 it will exit the program successfully from main or if enter 1 it will run through the fight function. However, if I go through 1 fight and get back the program asking me to either enter 1 or 2 to play or exit, I can enter 2 infinite times and it will not exit the program. I am not sure what it causing this.
for(;;)
{
game = menu();
if(game == 2)
{
break;
}
else
{
fight();
}
}
return 0;
The code inside the menu() function of my program is as follows and is where the rest of the input for my program is contained. I am using getline(cin, fighterName) to get a string from the user to use as a name for each character they want to create
The problem I am having is that it starts to just save the name of characters as empty without asking.
cout << "How many fighters should be on Team 1?" << endl;
//Input Validation
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> team1Size)
{
if(team1Size <= 0)
{
cout << "The team must be a size of at least 1 fighter. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
{
break;
}
}
else
{
cout << "You did not enter a valid number. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
cout << "How many fighters should be on Team 2?" << endl;
//Input Validation
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> team2Size)
{
if(team2Size <= 0)
{
cout << "The team must be a size of at least 1 fighter. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
{
break;
}
}
else
{
cout << "You did not enter a valid number. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//Set up team 1
cout << "Begin setup for team 1:" << endl << endl;
for(int i = 0; i < team1Size; i++)
{
cout << "Which character type should fighter " << i+1 << " be?" << endl;
cout << "1. Barbarian" << endl;
cout << "2. BlueMen" << endl;
cout << "3. Vampire" << endl;
cout << "4. Medusa" << endl;
cout << "5. Harry Potter" << endl;
cout << "Please enter the number corresponding to your choice from the list above." << endl;
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> fighterType)
{
if(fighterType < 1 || fighterType > 5)
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
break;
}
else
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//Now that we have the desired type of the fighter we must add a fighter of the correct type to the linked list
//representing team 1. We will do so by calling the add function of the linked list
cout << "Please enter the name of this fighter." << endl;
getline(cin, fighterName);
if(fighterType == 1)
{
team1.addBack("Barbarian", fighterName);
}
else if(fighterType == 2)
{
team1.addBack("BlueMen", fighterName);
}
else if(fighterType == 3)
{
team1.addBack("Vampire", fighterName);
}
else if(fighterType == 4)
{
team1.addBack("Medusa", fighterName);
}
else
{
team1.addBack("HarryPotter", fighterName);
}
}
cout << "Team 1 has been created!" << endl << endl;
//Set up team 2
cout << "Begin setup for team 2:" << endl << endl;
for(int i = 0; i < team2Size; i++)
{
cout << "Which character type should fighter " << i+1 << " be?" << endl;
cout << "1. Barbarian" << endl;
cout << "2. BlueMen" << endl;
cout << "3. Vampire" << endl;
cout << "4. Medusa" << endl;
cout << "5. Harry Potter" << endl;
cout << "Please enter the number corresponding to your choice from the list above." << endl;
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> fighterType)
{
if(fighterType < 1 || fighterType > 5)
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
break;
}
else
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//Now that we have the desired type of the fighter we must add a fighter of the correct type to the linked list
//representing team 2. We will do so by calling the add function of the linked list
cout << "Please enter the name of this fighter." << endl;
getline(cin, fighterName);
if(fighterType == 1)
{
team2.addBack("Barbarian", fighterName);
}
else if(fighterType == 2)
{
team2.addBack("BlueMen", fighterName);
}
else if(fighterType == 3)
{
team2.addBack("Vampire", fighterName);
}
else if(fighterType == 4)
{
team2.addBack("Medusa", fighterName);
}
else
{
team2.addBack("HarryPotter", fighterName);
}
}
cout << "Team 2 has been created!" << endl << endl;
cout << "Let the fight begin!" << endl << endl;
return 0;
}
The final piece of input from my code is the following which simply asks the user to enter a character either y or n and then executes a function if y is entered.
cout << "Would you like to see the contents of the loserPile?" << endl;
cout << "Please enter y for yes or n for no" << endl;
for(;;)
{
if(cin >> displayLosers)
{
if(displayLosers != 'y' && displayLosers != 'n')
{
cout << "You did not enter either y or n. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
break;
}
else
{
cout << "You did not enter either y or n. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
if(displayLosers == 'y')
{
losers.displayPile();
}
If someone could point out where I am making the error in obtaining user input I would appreciate it as I am running out of things to try that I know of.
You are creating a lot of problems by adding if(cin.get() == '.')
The >> operator will convert the input string "1." to 1, and if you call ignore(...,'\n') the . and any other characters before \n will be ignored. Test for if(cin >> number){...} is also not necessary. You can initialize the value to -1 to indicate an error:
int menuChoice;
for(;;)
{
menuChoice = -1;
cin >> menuChoice;
cout << menuChoice;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(menuChoice == 1 || menuChoice == 2)
{
cout << menuChoice << "\n";
break;
}
cout << "You did not enter a valid menu option. Please try again." << endl;
}
Just make sure you are using the right input. For Yes or No option the input should be char:
cout << "enter y or n\n";
for(;;)
{
char val;
cin >> val;
if(val != 'y' && val != 'n')
{
cout << "You did not enter either y or n. Please try again." << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
else
break;
}

Cin.get() not working second time i use it

#include <iostream>
#include <strings.h>
using namespace std;
void encyclopedia()
{
int choice;
int choice2;
system("CLS");
cout << "Content Menu\n\n"
<< "1. Gore\n\n"
<< "2. Wilson\n\n"
<< "3. Costa\n\n"
<< "Selection: ";
cin >> choice;
if (choice == 1)
{
system("CLS");
cout << "Al Gore's Book Summary of:\n\n"
<< "1. Introduction\n\n"
<< "2. \n\n"
<< "3. \n\n";
cin >> choice2;
if (choice2 == 1)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
else if (choice2 == 2)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
else if (choice2 == 3)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
}
if (choice == 2)
{
system("CLS");
cout << "Wilson's Book Summary of:\n\n"
<< "1. Introduction\n\n"
<< "2. \n\n"
<< "3. \n\n";
cin >> choice2;
if (choice2 == 1)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
else if (choice2 == 2)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
else if (choice2 == 3)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
}
if (choice == 3)
{
system("CLS");
cout << "Rebeca Costa's Book Summary of:\n\n"
<< "1. Introduction\n\n"
<< "2. \n\n"
<< "3. \n\n";
cin >> choice;
if (choice2 == 1)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
else if (choice2 == 2)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
else if (choice2 == 3)
{
system("CLS");
cout << "text here\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
}
}
int main()
{
cout << "2013 Written Task #2\n\nBy: Skye Leis\n\n";
cout << "Press enter to continue\n";
cin.get();
encyclopedia();
}
While my first cin.get() is working, I cannot get the cin.get()'s before my encyclopedia() to work. When it runs, the first screen works, then the contents menu works, and the sub menus work, but on the parts it displays the actual text, it doesn't wait for a entry key before restarting the encyclopedia function.
cin works on formatted input. Which means it will read up until it finds a blank space or a new line.
The problem is when you do
cin >> choice2;
When you enter a number and press enter, cin will read upto a blank space. Which means the newline (from key enter) is still on there. Your cin.get will read that new line character and continues.
In addition if I enter two numbers separated by space, your implementation will take the second number and use it for any of the next menu inputs.
To make sure that anything left on the input is read before you continue to the next menu item you can use getline()
string garbage;
cin >> choice2;
getline(cin, garbage); // The will take care of any extra inputs.
What happens is there are still leftovers(endlines) so you might be getting some other unwanted chars after the user type, try adding:
cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
after cin
It reads last /n
and do:
cin.clear(); cin.get();
or just write cin.get(); twice