c++ Input Validation printing twice? - c++

Don't know why it is printing twice. This is just practice I am trying to use cin.clear() / cin.ignore though. Trying to write a menu with functions inside switch statements.
#include <iostream>
#include <iomanip>
using namespace std;
void showMenu();
void showFees(double, int);
int main()
{
int choice;
int months;
const int ADULT_CHOICE = 1;
const int CHILD_CHOICE = 2;
const int SENIOR_CHOICE = 3;
const int QUIT_CHOICE = 4;
const double ADULT = 40.0;
const double CHILD = 20.0;
const double SENIOR = 30.0;
do
{
showMenu();
cin >> choice;
while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: ";
cin.clear();
cin.ignore(INT_MAX, '\n');
}
if (choice != QUIT_CHOICE)
{
cout << "For how many months? ";
cin >> months;
switch (choice)
{
case ADULT_CHOICE:
showFees(ADULT, months);
break;
case CHILD_CHOICE:
showFees(CHILD, months);
break;
case SENIOR_CHOICE:
showFees(SENIOR, months);
break;
}
}
} while (choice != QUIT_CHOICE);
system("pause");
return 0;
}
void showMenu()
{
cout << "\nHealth Club Membership Menu" << endl << endl;
cout << "1. Standard Adult Membership" << endl;
cout << "2. Child Membership" << endl;
cout << "3. Senior Citizen Membership" << endl;
cout << "4. Quit the Program" << endl << endl;
cout << "Enter your choice: ";
}
void showFees(double memberRate, int months)
{
cout << "The total charges are $" << (memberRate * months) << endl;
}
This is what it's printing. I'm fairly new c++, so I'm not really sure what's wrong. Is it the spacing? No clue.
Health Club Membership Menu
1. Standard Adult Membership
2. Child Membership
3. Senior Citizen Membership
4. Quit the Program
Enter your choice: 0
Please enter a valid menu choice: Please enter a valid menu choice: 0
Please enter a valid menu choice:

You have forgotten to read input again:
cin >> choice;
while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: ";
cin.clear();
cin.ignore(INT_MAX, '\n');
}
You read your input once. Then you go into the while check choice, You do cin.clear() and cin.ignore() and once again your loop executes as no new data has been passed: This should do the job:
cin >> choice;
while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: ";
cin.clear();
cin.ignore(INT_MAX, '\n');
cin >> choice;
}

The input stream looks like this:
0\n
You first read the 0, and now the stream is
\n
The 0 is invalid, so you print "Please enter a valid menu choice: " and skip over the newline.
The stream is now empty.
Since the value of choice hasn't changed, it's still invalid and you print "Please enter a valid menu choice: " again.
This time the input stream is empty, so the ignore has to wait for the next newline, and that's why you're getting two outputs only the first time.
If you instead had done the output after you were done with the input processing:
cin.clear();
cin.ignore(INT_MAX, '\n');
cout << "Please enter a valid menu choice: ";
the output woldn't have been repeated.
A different bug is that the loop never exits, even if you input a valid value.
The reason for this is that you never read a new value for choice.
You need to add
cin >> choice;
at the end of the validation loop.

Problem is here:
while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: ";
cin.clear();
cin.ignore(INT_MAX, '\n');
}
Try this code. You must read value to variable choice again.
while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: " << endl;
cin >> choice;
cout << endl;
}

Related

No output is shown when option 2 is chosen in C++

So after I enter my input in option 1, then I chose to continue. My input information are gone when choosing the option 2.
I just started my programming course so please give me a lot of advice.
This is the output enter image description here
struct Human
{
string name;
string foods;
string date;
};
char option;
int main()
{
do
{
int user;
cout << "You" <<endl;
cout << "\nChoose one from the menu below" <<endl;
cout << "1 Enter information" <<endl;
cout << "2 See information stored" <<endl;
cout << "\nEnter your option" <<endl;
cin >> user;
Human me;
switch(user)
{
case 1:
{
cin.ignore(100, '\n');
cout << "\nEnter your name: ";
getline(cin, me.name, '\n');
cout << "Enter your favorite foods: ";
getline(cin, me.foods, '\n');
cout << "Enter your birthday: ";
getline(cin, me.date, '\n');
break;
}
case 2:
{
cin.ignore(100, '\n');
cout << "Your name is: " << me.name<<endl;
cout << "Your favorite foods are: " <<me.foods<<endl;
cout << "Your birthday is: " <<me.date<<endl;
break;
}
}
cout << "\nDo you wish to continue?" <<endl;
cout << "Enter 'y' to continue and 'n' to exit" <<endl;
cout << "Your choice:";
cin >> option;
}while(option == 'y');
return 0;
}
You create a new Human me; in every iteration of the do-while loop. When you read input for that me in one iteration, the me in the next iteration won't know about that.
Read about "scope" and moving the declaration Human me; outside of the loop will probably do what you expect.
#include<iostream>
using namespace std;
struct Human
{
string name;
string foods;
string date;
};
char option;
int main()
{
Human me;
do
{
int user;
cout << "You" <<endl;
cout << "\nChoose one from the menu below" <<endl;
cout << "1 Enter information" <<endl;
cout << "2 See information stored" <<endl;
cout << "\nEnter your option" <<endl;
cin >> user;
switch(user)
{
case 1:
{
cin.ignore(100, '\n');
cout << "\nEnter your name: ";
getline(cin, me.name, '\n');
cout << "Enter your favorite foods: ";
getline(cin, me.foods, '\n');
cout << "Enter your birthday: ";
getline(cin, me.date, '\n');
break;
}
case 2:
{
cin.ignore(100, '\n');
cout << "Your name is: " << me.name<<endl;
cout << "Your favorite foods are: " <<me.foods<<endl;
cout << "Your birthday is: " <<me.date<<endl;
break;
}
}
cout << "\nDo you wish to continue?" <<endl;
cout << "Enter 'y' to continue and 'n' to exit" <<endl;
cout << "Your choice:";
cin >> option;
}while(option == 'y');
return 0;
}
So, Here is The Working Code problem is that you declare struct variable in the loop so every time loop runs it gets again initialized and previous lost
enter image description here

Switch statements with while loops

do{
cout << "Select an option from the Menu: ";
cin >> choice;
// Validate the menu selection
while ((choice < 1) || (choice > 3)){
cout << "Incorrect input!, please enter an option from 1 to 3."<<endl;
cout<<"Enter your choice: ";
cin >> choice;
}
// Processing the users choice
if (choice != 3){
// Compute conversions
switch (choice){
case 1:
cout<<""<<endl;
cout<<"You have selected to convert Fijian Dollars to Vanuatuan Vatu."<<endl;
cout<<"Enter the amount you wish to convert: ";
cin >> amount;
conversion = amount * FJD_to_Vatu_Rate;
break;
case 2:
cout<<""<<endl;
cout<<"You have selected to convert Fijian Dollars to Samoan Tala."<<endl;
cout<<"Enter the amount you wish to convert: ";
cin >> amount;
conversion = amount * FJD_to_Tala_Rate;
break;
case 3:
cout<<"Here the history will be shown"<<endl;
cout<<""<<endl;
cout<<"Do You want to perform another conversion? (Y/N) ";
cin >> repeat;
if (repeat == 'Y'){
(This is what i want to know)
}
cout<<"Thank you for using this program, goodbye!"<<endl;
return 0;
}
// Display the monthly charges
cout << fixed << showpoint << setprecision(2);
cout << "The converted amount is: " << conversion << endl;
cout <<""<<endl;
}
} while (choice != 3);
cout<<"Thank you for using this program, goodbye!"<<endl;
return 0;
}
The above is my part of my code for a currency converter, can anyone tell me if what to do in the section where it says "this is what i want to know" so that the program asks user to enter a choice so it can process it and use the choice to compute using one of the other cases.
Thanks
Remove your if statement before switch because case 3: will never be executed in this case.
do{
cout << "Select an option from the Menu: ";
cin >> choice;
// Validate the menu selection
while ((choice < 1) || (choice > 3)){
cout << "Incorrect input!, please enter an option from 1 to 3."<<endl;
cout<<"Enter your choice: ";
cin >> choice;
}
// Processing the users choice
// Compute conversions
switch (choice){
case 1:
cout<<""<<endl;
cout<<"You have selected to convert Fijian Dollars to Vanuatuan Vatu."<<endl;
cout<<"Enter the amount you wish to convert: ";
cin >> amount;
conversion = amount * FJD_to_Vatu_Rate;
break;
case 2:
cout<<""<<endl;
cout<<"You have selected to convert Fijian Dollars to Samoan Tala."<<endl;
cout<<"Enter the amount you wish to convert: ";
cin >> amount;
conversion = amount * FJD_to_Tala_Rate;
break;
case 3:
cout<<"Here the history will be shown"<<endl;
cout<<""<<endl;
cout<<"Do You want to perform another conversion? (Y/N) ";
cin >> repeat;
if (repeat == 'Y'){
(This is what i want to know)
}
cout<<"Thank you for using this program, goodbye!"<<endl;
return 0;
// Display the monthly charges
cout << fixed << showpoint << setprecision(2);
cout << "The converted amount is: " << conversion << endl;
cout <<""<<endl;
}
} while (choice != 3);
cout<<"Thank you for using this program, goodbye!"<<endl;
return 0;
}
To restart do-while loop use continue. Logically you should print history first first, then do question\check.

while loop infinite validation response to incorrect input

In the case deposit section i have written a loop to validate that the user input is a integer but upon entering something other than an integer it assigns that to the variable credit and repeatedly displays "Please enter an amount greater than £1" i have tried to make it clear the input upon displaying the message so the process can be repeated but i cannot seem to get it to clear the variable of the incorrect input.
#include <iostream>
#include <string>
using namespace std;
enum Menusystem // enum is a function used to convert the list of words below into numbers.
{
ShowMenu, EnterName, Account, Deposit, Withdraw, Balance, Exit
} menu;
int main()
{
string customer; // declaring variables and their data types for the menu options.
string accounttype;
string name;
int credit;
int debit;
int currentbal;
bool exit = false; // declaring variable as boolean setting it to false so that when the loop gets to false it will break the loop and exit the program.
int option = 0; // declares showmenu as a integer and sets value to 0 so that the menu will be displayed upon opening the program as in the code below the menu is displayed if option is equal to 0.
while (!exit) // initiates a while loop so that when the loop gets to false it will break the loop and exit the program.
{
switch (menu) // initiates a switch statement which will allow the program to cycle through menu options depending on the menu option the user selects.
{
case ShowMenu:
cout << "[0] - Show menu\n" // displays menu options to user.
<< "[1] - Enter Full Name\n"
<< "[2] - Enter Account Type\n"
<< "[3] - Deposit Funds\n"
<< "[4] - Withdraw Funds\n"
<< "[5] - Display Balance\n"
<< "[6] - Exit Program\n";
cin >> option;
if (option == 0) menu = ShowMenu;
else if (option == 1) menu = EnterName;
else if (option == 2) menu = Account;
else if (option == 3) menu = Deposit;
else if (option == 4) menu = Withdraw;
else if (option == 5) menu = Balance;
else if (option == 6) menu = Exit;
else menu = ShowMenu; // default case is to show the menu.
break;
case EnterName:
system("CLS");
cout << "Please enter your full name >\n";
cin >> customer;
system("CLS");
menu = ShowMenu;
break;
case Account:
menu = ShowMenu;
break;
case Deposit:
system("CLS");
cout << "Please enter an amount you wish to deposit >\n";
cin >> credit;
while (!(cin >> credit)) cout << "Please enter an amount greater than £1";
{
cin.clear();
cin.ignore(100, '\n');
}
system("CLS");
menu = ShowMenu;
break;
case Withdraw:
system("CLS");
cout << "Please enter an amount you wish to withdraw >\n";
cin >> debit;
system("CLS");
menu = ShowMenu;
break;
case Balance:
cout << credit;
cout << customer;
break;
case Exit:
break;
default:
break;
}
}
return 0;
This statement:
while (!(cin >> credit)) cout << "Please enter an amount greater than £1";
{
cin.clear();
cin.ignore(100, '\n');
}
is not doing what you think it is. It's doing the equivalent of this:
while (!(cin >> credit)) {
cout << "Please enter an amount greater than £1";
}
cin.clear();
cin.ignore(100, '\n');
You need to move the cout statement into the loop, like this:
while (!(cin >> credit)) {
cout << "Please enter an amount greater than £1";
cin.clear();
cin.ignore(100, '\n');
}

Code to get user input not executing/skipping in C++

In the below code, I'm running into an error when I try to get the user to input their name. My program just skips it over and goes right over to making the function calls without allowing the user to enter their name. Despite the error, my program is compiling. I'm not sure what's going wrong as I wrote that part based off other examples I found on here. Any suggestions?
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
char showMenu();
void getLottoPicks(int[]);
void genWinNums(int[]);
bool noDuplicates(int[]);
const int SIZE = 7;
int main()
{
int userTicket[SIZE] = {0};
int winningNums[SIZE] = {0};
char choice;
string name;
srand(time(NULL));
do
{
choice = showMenu();
if (choice == '1')
{
cout << "Please enter your name: " << endl;
getline(cin, name);
getLottoPicks(userTicket);
genWinNums(winningNums);
for (int i = 0; i < SIZE; i++)
cout << winningNums[i];
}
} while (choice != 'Q' && choice != 'q');
system("PAUSE");
return 0;
}
Added the code for showMenu:
char showMenu()
{
char choice;
cout << "LITTLETON CITY LOTTO MODEL:" << endl;
cout << "---------------------------" << endl;
cout << "1) Play Lotto" << endl;
cout << "Q) Quit Program" << endl;
cout << "Please make a selection: " << endl;
cin >> choice;
return choice;
}
And getLottoPicks (this part is very wrong and I'm still working on it):
void getLottoPicks(int numbers[])
{
cout << "Please enter your 7 lotto number picks between 1 and 40: " << endl;
for (int i = 0; i < SIZE; i++)
{
cout << "Selection #" << i + 1 << endl;
cin >> numbers[i];
if (numbers[i] < 1 || numbers[i] > 40)
{
cout << "Please choose a number between 1 and 40: " << endl;
cin >> numbers[i];
}
if (noDuplicates(numbers) == false)
{
do
{
cout << "You already picked this number. Please enter a different number: " << endl;
cin >> numbers[i];
noDuplicates(numbers);
} while (noDuplicates(numbers) == false);
}
}
}
After doing cin >> choice; inside char showMenu(), if a user inputs 1[ENTER], the char consumes 1 character from cin, and the newline stays inside the stream. Then, when the program gets to getline(cin, name);, it notices that there's still something inside cin, and reads it. It's a newline character, so getline gets it and returns. That's why the program is behaving the way it is.
In order to fix it - add cin.ignore(); inside char showMenu(), right after you read the input. cin.ignore() ignores the next character - in our case, the newline char.
And a word of advice - try not to mix getline with operator >>. They work in a slightly different way, and can get you into trouble! Or, at least remember to always ignore() after you get anything from std::cin. It may save you a lot of work.
This fixes the code:
char showMenu()
{
char choice;
cout << "LITTLETON CITY LOTTO MODEL:" << endl;
cout << "---------------------------" << endl;
cout << "1) Play Lotto" << endl;
cout << "Q) Quit Program" << endl;
cout << "Please make a selection: " << endl;
cin >> choice;
cin.ignore();
return choice;
}
from looking at code showMenu function has problem. and it's not returning asccii equivalent of '1' that is: 31 integer. try printing value returned by showmenu. you will get that
UPDATE:
It is because cin in delimited by ' '(whitespace) and getline by '\n' character, so when enter name and press enter cin in showmenu will consume whole string except '\n' from istream and that is read by getline. to see this when it ask for choice enter string like 1 myname (1 whitespace myname)and press ENTER will display name. now cin will read 1 in choice and myname in name by getline.

C++ console not showing menu

If the user selects 1 or 2, function doesn't run. Any suggestions?
#include <iostream>
using namespace std;
void getTitle();
void getIsbn();
int main()
{
int choice = 0; // Stores user's menu choice
do
{
// Display menu
cout << " Main Menu\n\n\n";
// Display menu items
cout << " 1. Choose 1 to enter Title.\n";
cout << " 2. Choose 2 to enter ISBN.\n";
cout << " 3. Choose 3 to exit.\n";
// Display prompt and get user's choice
cout << " Enter your choice: ";
cin >> choice;
// Validate user's entry
while (choice < 1 || choice > 3)
{
cout << "\n Please enter a number in the range 1 - 3. ";
cin >> choice;
}
switch (choice)
{
case 1:
getTitle();
break;
case 2:
getIsbn();
break;
}
} while (choice != 3);
return 0;
}
void getTitle()
{
string title;
cout << "\nEnter a title: ";
getline(cin, title);
cout << "\nTitle is " << title << "\n\n\n";
}
void getIsbn()
{
string isbn;
cout << "\nEnter an ISBN: ";
getline(cin, isbn);
cout << "\nISBN is " << isbn << "\n\n\n";
}
The functions should certainly get called. What will happen, though, is that the newline generated when you press "Enter" to type the number will get returned by the getline(), and the function will return without really prompting you. You need to clear that newline. You can use ignore() to do this: add cin.ignore(); immediately after reading in choice to ignore the one character.