This question already has answers here:
How to test whether stringstream operator>> has parsed a bad type and skip it
(5 answers)
How to handle wrong data type input
(4 answers)
Closed 1 year ago.
I have a switch statement (copied in below) with cases and a default function, but if I enter a string, the code loops endlessly. How can I prevent this? Do I need to move something outside of the do loop? Use a different loop? I'm new to c++ and don't know how I can fix this, despite having tried moving things out of the loop.
void menu() //Opens new function, called menu, which will contain all code for the menu screen.
{
cout << setw(60); //Sets the screen width to 60 in order to centre all outputted text on the menu screen.
std::string text; //Declares the variable "text" as a string.
int choice{}; //Declares an integer "choice" that will contain the menu input.
int choicex{}; //Declares an integer "choicex" that will contain the input that will determine virus activation.
bool valid_input = false;
cout << setw(60);
cout << "ARES" << endl;
cout << setw(61);
std::cout << "MENU\n";
cout << setw(78);
std::cout << "Select one of the following options:\n";
cout << setw(67);
std::cout << "1. Activate Virus\n";
cout << setw(70);
std::cout << "2. Program Information\n";
cout << setw(62);
std::cout << "3. Exit\n";
do
{
std::cin >> choice;
switch (choice)
{
case 1:
system("CLS");
cout << setw(84);
std::cout << "Are you sure? Press 1 to continue, or 2 to go back."; // Prints the spaces
std::cin >> choicex;
if (choicex == 1)
{
system("CLS");
Ares();
}
if (choicex == 2)
{
system("CLS");
menu();
}
if (choicex != 1 and choicex != 2)
{
system("CLS");
cout << setw(80);
std::cout << "Invalid Input. Redirecting to menu.\n";
cout << setw(90);
system("pause");
system("CLS");
menu();
}
case 2:
ProgramInfo();
case 3:
system("CLS");
exit(EXIT_FAILURE);
default:
system("CLS");
cout << setw(60);
std::cout << "Invalid input.\n";
cout << setw(66);
std::cout << "Redirecting to menu.\n";
cout << setw(70);
std::cout << "Press any key to continue.\n";
std::cin.ignore();
system("CLS");
menu();
}
}
while (choice < 1 or choice > 3);
}
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 11 months ago.
Improve this question
Hi I'm trying to use a cin input but on my second while loop, the inputs are not running though correctly. How would I go about this?
Here's what I have:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using std::endl;
using std::cout;
using std::cin;
using namespace std;
int a, A;
int main() {
int choice, num;
cout << "State Search" << endl;
cout << "" << endl;
cout << "1. Enter the first letter of your desired state" << endl;
cout << "2. Press 2 to Quit" << endl;
cout << "" << endl;
bool done = false;
while(!done) {
//user inputs desired choice
cin >> choice;
if(choice == a || choice == A)
{
cout << "Which State? (enter a number)" << endl;
cout << "1. Alabama" << endl;
cout << "2. Alaska" << endl;
cout << "3. Arizona" << endl;
cout << "" << endl;
while (!(cin >> num))
{
if(num == 1)
{
cout << "test output 1" << endl;
}
else if (num == 2)
{
cout << "test output 2" << endl;
}
else if (num == 3)
{
cout << "test output 3" << endl;
}
} break;
} break;
}
return 0;
}
Once the user chooses one of the above states using a number I want to display the chosen output.
Here is a cleaned up version of what you are trying to do with some inline comment where you were going wrong.
// You only need to include iostream in your example program
// Only include what you need
#include <iostream>
#include <limits>
// You do not need to include all of the std namespace in the local scope
// if you are using the things you want.
using std::endl;
using std::cout;
using std::cin;
using std::streamsize;
int main()
{
cout << "State Search\n\n";
cout << "1. Enter the first letter of your desired state\n";
cout << "2. Press 2 to Quit\n" << endl;
// Removed all the while(!done) / break; as it is just noise in the current iteration of your program.
// if you use an int for the choice variable, you will actually try to parse the input
// as an integer and return 0 if the user inputs 'a'
// you need to use a char for what you want to do
char choice;
cin >> choice;
// Also your a and A int value do not make sense as they are init to 0
// (global initialization), I guess what you want to do is compare to the char 'a' or 'A'. You could also transform the input to lowercase and compare only to 'a'.
if (choice == 'a' || choice == 'A')
{
// Use \n not std::endl as it will flush the output buffer
// all the time. std::endl is a false friend, use it only
// when you want to present your text to the user.
cout << "Which State? (enter a number)\n";
cout << "1. Alabama\n";
cout << "2. Alaska\n";
cout << "3. Arizona\n" << endl;
// We want to wait until we get a correct input and _then_
// do something with our input.
int num;
while (!(cin >> num))
{
// You might want to say something to your user if he doesn't input a correct number here.
// This will succeed if the user inputs 4, so you might also want to handle that case differently and ask the user to retry too in that case.
// The stream is now in error, you need to reset the state of the stream by clearing the error and emptying the buffer.
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
}
// Just showing another way of doing the if / else if dance in C/C++.
switch(num)
{
case 1: cout << "You chose Alabama" << endl; break;
case 2: cout << "You chose Alaska" << endl; break;
case 3: cout << "You chose Arizona" << endl; break;
default: cout << "I do not recognize the State" << endl; break;
}
}
// if we didn't receive 'a' or 'A' we just quit the program.
return 0;
}
So I have a Menu that I used to run my text based game. The problem is that I can't seem to exit my game.Every time I run it, I can do option 1 and go to my game, and options 2 and 3 work just fine. But For option 4, I am unable to exit my game. All it does is print out what I ask it to print out, before giving the menu options again (as if it was just looping).
I have googled a lot, and tried to figure out why but I am not sure.
If someone can advise me what to do or tell me where my mistake is, it would be greatly appreciated. Please let me know if you want to see more code. All I have displayed here is the Menu Function.
void menu() {
char choice = -1;
while(choice != '1')
{
cout << "\n* * * * *" << endl;
cout << " The Dark Maze\n";
cout << "\n* * * * *" << endl;
cout << "\n=====================";
cout << "\n Main Menu |";
cout << "\n=====================";
cout << "\n 1 - Start Game |";
cout << "\n 2 - Instructions |";
cout << "\n 3 - Storyline |";
cout << "\n 4 - Exit |";
cout << "\n=====================";
cout << "\n";
cout << "\n Enter choice: ";
cout << "\n";
cin >> choice;
switch (choice)
{
case '1':
cout << "\n" << endl;
cout << "\n But we can't start the game just yet..." << endl;
break; //heads to game
case '2':
Instructions();
break;
case '3':
Storyline();
break;
case '4':
cout << "\n Well, if you really don't want to play... you don't have to." << endl;
break; //just say exit?? break isnt making it stop
default:
cout << "Invalid Character entered\n";
cout << "\n";
cout << "Press Space to continue\n";
}// end of switches
cin.get();
} // end of while
}// end of menu
You shouldn't be using while loop for this. Try do-while loop for this kind of menus like this:
do
{
// your menu here...
cin >> choice;
switch ( choice )
{
case ...
...
}
// cin.get();
// ^^^^^^^^^^ You don't need this...
} while ( choice != '4' );
Some points to help you:
Use an enum to define your menu choices. (OR an enum class).
You can simply write a printMenu() function to print the menu in the main loop. Another function to process the choice.
For example:
void startGame()
{
char choice = INVALID_OPTION; // INVALID_OPTION => default invalid value
do
{
printMenu();
cin >> choice;
processChoice( choice );
} while ( choice != EXIT ); // EXIT => #define or an enum
}
You can use exit() to terminate your program with a given return value:
case '4':
std::cout << "blahblahblah";
std::exit(0);
break; // No longer necessary
It's prerequisite and prototype is
#include <cstdlib>
namespace std{
void exit(int status);
}
just use return instead break blow case '4' . not perfect but can work.
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');
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'm having trouble with this do-while loop menu for a program I'm working on for school. I've checked, and as far as I'm concerned I have written the code correctly. However, when testing, if I type 'y' or 'n' the result is the same: the menu streaming down 100's of times non stop until I exit the program. Any idea on what I'm doing wrong and how I can get it to display the menu properly every time? Thanks in advance.
#include <iostream>
#include <iomanip>
#include <string>
#include "CashRegister.h"
#include "InventoryItem.h"
using namespace std;
int main()
{
// Variables
int selection, numUnits, cont;
double price;
// Use the first constructor for the first item
InventoryItem item1;
item1.setCost(5.0);
item1.setDescription("Adjustable Wrench");
item1.setUnits(10);
// Use the second constructor for the second item
InventoryItem item2("Screwdriver");
item2.setCost(3.0);
item2.setUnits(20);
// Use the third constructor for the remaining items
InventoryItem item3("Pliers", 7.0, 35);
InventoryItem item4("Ratchet", 10.0, 10);
InventoryItem item5("Socket Wrench", 15.0, 7);
do
{
cout << "#\t" << "Item\t\t\t" << "qty on Hand" << endl;
cout << "------------------------------------------------------------------" << endl;
cout << "1\t" << item1.getDescription() << "\t" << setw(3) << item1.getUnits() << endl;
cout << "2\t" << item2.getDescription() << "\t\t" << setw(3) << item2.getUnits() << endl;
cout << "3\t" << item3.getDescription() << "\t\t\t" << setw(3) << item3.getUnits() << endl;
cout << "4\t" << item4.getDescription() << "\t\t\t" << setw(3) << item4.getUnits() << endl;
cout << "5\t" << item5.getDescription() << "\t\t" << setw(3) << item5.getUnits() << endl;
cout << "Which item above is being purchased? ";
cin >> selection;
// Validate the selection
while (selection < 1 || selection > 5)
{
cout << "Error, please make a valid item selection: ";
cin >> selection;
}
cout << "How many units? ";
cin >> numUnits;
// Validate the quantity of units to make sure it isn't a negative value
while (numUnits < 0)
{
cout << "Error, please enter a valid quantity: ";
cin >> numUnits;
}
// Use a switch statement to figure out which cost to pull
switch (selection)
{
case 1: {price = item1.getCost();
item1.changeUnits(numUnits); }
break;
case 2: {price = item2.getCost();
item2.changeUnits(numUnits); }
break;
case 3: {price = item3.getCost();
item3.changeUnits(numUnits); }
break;
case 4: {price = item4.getCost();
item4.changeUnits(numUnits); }
break;
case 5: {price = item5.getCost();
item5.changeUnits(numUnits); }
break;
}
// Create a CashRegister object for this particular selection
CashRegister transaction(price, numUnits);
// Display the totals
cout << fixed << showpoint << setprecision(2);
cout << "Subtotal: $" << transaction.getSubtotal() << endl;
cout << "Sales Tax: $" << transaction.getSalesTax() << endl;
cout << "Total: $" << transaction.getPurchaseTotal() << endl;
// Find out if the user wants to purchase another item
cout << "Do you want to purchase another item? Enter y/n: ";
cin >> cont;
} while (cont != 'n' && cont != 'N');
system("pause");
return 0;
}
Your loop will never break unless you explicitly enter 110 which is the 'n' char in ASCII Codes or 78 which is the 'N'. So change your cont declaration from int cont; to char cont; and then you won't get the infinite loop anymore, and its condition will be valid to possibly break by then unless you have another hidden logical error which will require you to debug it.
i need to prevent the junk left in the buffer as entering a value for a switch case menu from being used in a function called by the menu where their is user input.
menu code
void menu()
{
bool done = false;
string input;
while(!done)
{
cout << "Welcome to the DVD database." << endl;
cout << "1. Add A DVD" << endl;
cout << "2. Delete a DVD." << endl;
cout << "3. Edit a DVD." << endl;
cout << "4. List By Category." << endl;
cout << "5. Retrieve by a DVD by Title." << endl;
cout << "6. Display collection by year" << endl;
cout << "7. Display collection by title" << endl;
cout << "-999. Exit program" << endl;
cout << "Please choose an option by entering the corresponding number" << endl;
cin >> input;
int value = atoi(input.c_str());
switch(value)
{
case 1:addDVD(); break;
case 2:deleteDVD(); break;
// case 3:editDVD(); break;
case 4:listByCategory();break;
case 6:displayByYear();break;
case 7:displayByTitle();break;
case -999: writeToFile(); exit(0); break;
default : cout <<"Invalid entry"<< endl; break;
}
}
}
void retrieveByTitle()
{
string search;
int size = database.size();
int index = 0;
bool found = false;
cin.ignore();
cout << "Please enter the title of the DVD you would like to retrieve: " << endl;
getline(cin,search);
cout << search;
while(!found && index<size)
{
if(database.at(index)->getTitle().compare(search)==0)
{
cout << database.at(index)->toString();
break;
}
}
cout << endl;
}
if 5 is entered in the menu, the program skips the user input in the method
This code works, but it has the same problem you describe if you eliminate the 'cin.ignore()', which removes the extra delimiters ignored by the cin >> operator:
#include <iostream>
#include <climits>
using namespace std;
int main() {
string a, b;
while (true) {
cout << "write 'x' to exit: " << endl;
cin >> a;
if (a == "x") {
break;
}
cout << "read '" << a << "'" << endl;
cout << "now write a line: " << endl;
cin.clear(); // clears cin status
cin.ignore(INT_MAX); // clears existing, unprocessed input
getline(cin, a);
cout << "read '" << a << "'" << endl;
}
return 0;
}
When dealing with interactive user input you should use std::getline()
The std::cin is flushed to the application every time you hit <enter>. So this is the logical junks you should read data from the user in.
std::string answer;
std::cout << "Question:\n";
std::getline(std::cin, answer);
This gets you everything the user provided in response to the previous question.
Once you have the input you should get the value you think is on the input. Once you have this you should check if there is any other junk on the input (if there is then abort and re-try) otherwise validate the data you expected.
If you were expected an integer;
std::stringstream linestream(answer);
int value;
std::string junk;
if ((answer >> value)) && (!(answer >> junk)))
{
// If you got data
// and there was no junk on the line you are now good to go
}
In your specific example there is already a simple way to do this:
std::getline(std::cin, input);
int value = boost::lexical_cast<int>(input); // throws an exception if there is not
// an int on the input (with no junk)