Why do I need to press Enter twice after getline()? - c++

Everything is working fine in this program except when it reaches getline() after cout<<"From Date: ";. At this point no matter if I give input or simply hit enter without input, I have to hit enter twice to proceed further. I tried removing cin.ignore() but it causes more problem by jumping over the first getline(). Here is the snippet which is causing this problem-
int main() {
Date d1;
int choice;
cout << "\nEnter choice: ";
cin >> choice;
cin.ignore(numeric_limits < streamsize > ::max(), '\n');
switch (choice) {
case 1:
d1.diffbw();
break;
default:
cout << "Wrong choice";
}
return 0;
}
void Date::diffbw() {
Date current, ref;
string choice;
cout << "\n Type 'man' to enter date manually else hit Enter to insert current date!";
do {
cout << "From Date:";
getline(cin, choice);
if (choice == "man")
current.getdate(); //getdate() assigns day, month and year in object current
else if (choice.empty())
current = sysDate(); //sysDate returns system date
else {
cout << "\n Wrong Choice!";
cout << "\n Enter Again?(y/n): ";
getline(cin, choice);
}
} while (choice == "y" || choice == "Y");
do {
cout << "To Date:";
getline(cin, choice);
if (choice.empty())
ref = sysDate();
else if (choice == "man")
ref.getdate();
else {
cout << "\n Wrong Choice!";
cout << "\n Enter Again?(y/n): ";
getline(cin, choice);
}
} while (choice == "y" || choice == "Y");
current.calcAge(ref); //calcAge() calculates difference between two given dates.
cout << "\n Difference: ";
cout << abs(current.day) << " day(s) " << abs(current.month) << " month(s) " << abs(current.year) << " year(s)";
}
P.S.- I am using g++ compiler on windows.
Edit: I posted the whole function here as many people are having difficulty in understanding the context here. I also corrected the 'cin.ignore()' syntax as suggested by #john. I am trying to calculate difference between two given dates.
The second 'do while' loop works without any bug although it is completely synonymous with the first one.

It might be because you are first trying to get a value by calling cin.getline() and afterwards the program is done but is waiting for confirmation and it gets the confirmation by you pressing enter.
Basically
Enter Value: 5 //Presses enter
Press any key to exit window.

Your statement
cout<<"\n\n From Date:";
is strange and probably wrong, since the std::cout stream is generally buffered.
You should use std::cout << "From date:" << std::endl; and read a good C++ programming book and check in this C++ reference that you are correctly using every function or feature from the C++ standard library.
If you compile with a recent GCC, I recommend enabling all warnings and debug info, so compiling with g++ -Wall -Wextra -g. Then use your debugger, e.g. GDB.
If your computer runs some Linux or POSIX system, you could be interested in using GNU readline: then the input line becomes user-editable. You might also want to code a graphical application with Qt.
Everything is working fine in this program
How did you check that? What debugger did you use? What test cases do you have? Did you try to type something with spaces, e.g. today's date as the user input? What did happen?

I slightly modified your program to avoid relying on the Date class, which you did not define:
#include <string>
#include <iostream>
#include <limits>
#include <math.h>
#include <stdio.h>
using namespace std;
void diffbw();
int main() {
int choice;
cout << "\nEnter choice: ";
cin >> choice;
cin.ignore(numeric_limits < streamsize > ::max(), '\n');
switch (choice) {
case 1:
diffbw();
break;
default:
cout << "Wrong choice";
}
}
void diffbw() {
string choice;
cout << "\n Type 'man' to enter date manually else hit Enter to insert current date!";
do {
cout << "From Date:";
getline(cin, choice);
cout << "choice";
if (choice == "man") {
}
else if (choice.empty()) {
}
else {
cout << "\n Wrong Choice!";
cout << "\n Enter Again?(y/n): ";
getline(cin, choice);
}
} while (choice == "y" || choice == "Y");
do {
cout << "To Date:";
getline(cin, choice);
if (choice.empty()) {
}
else if (choice == "man") {
}
else {
cout << "\n Wrong Choice!";
cout << "\n Enter Again?(y/n): ";
getline(cin, choice);
}
} while (choice == "y" || choice == "Y");
cout << "\n Difference: ";
}
and I don't see the same phenomenon you describe. That is, I don't need to press Enter twice. Please consider making your problematic program more minimal, and at the same time complete.

Related

Using goto function one of my user inputs won't work (c++)

I am writing a program that lets the user make their own person (as an object) with a series of user inputs and multiple choice. I have a confirmation system at the end using the goto function but when i go back to making making the person if they don't like it the user input for the fist name won't work but the rest do (the first name user input works the first time round perfectly fine)
Here is the code and an explanation:
Setting things up,making the class with a basic constructor function added on.
#include <iostream>
using namespace std;
class Person{
public:
string FirstName;
string Surname;
string Gender;
int Age;
double Money;
Person(string aFirstName, string aSurname, string aGender, int aAge, double aMoney){
FirstName = aFirstName;
Surname = aSurname;
Gender = aGender;
Age = aAge;
Money = aMoney;
}
};
Making the variables that will be put in the person at the end and getting them with user inputs and multiple choice:
int main(){
Error2:
string bFirstName;
string bSurname;
string bGender;
int bAge;
int Choice1;
int YesNo;
cout << "What is your character's First Name?" <<endl;
getline(cin, bFirstName);
cout << "What is your character's Surname?" <<endl;
getline(cin, bSurname);
Error1:
cout << "What is your character's Gender?" <<endl;
cout << "Press 1 for Male" <<endl;
cout << "Press 2 for Female" <<endl;
cout << "Press 3 for Other" <<endl;
cin >> Choice1;
switch(Choice1){
case 1:
bGender = "Male";
break;
case 2:
bGender = "Female";
break;
case 3:
cout << "Type in Gender." <<endl;
cin >> bGender;
break;
default:
cout << "Enter a valid choice next time" <<endl;
goto Error1;
break;
}
cout << "What is your character's Age?" <<endl;
cin >> bAge;
The confirmation system using goto functions so they can scrap the one they made and make a new one:
Error3:
cout << "Are you sure you want your character to have these attributes?" <<endl;
cout << "1 for yes, 2 for no" <<endl;
cout << "FirstName: " << bFirstName <<endl;
cout << "Surname: " << bSurname <<endl;
cout << "Gender: " << bGender <<endl;
cout << "Age: " << bAge <<endl;
cin >> YesNo;
if(YesNo == 1){
goto Error4;
} else if(YesNo == 2){
goto Error2;
} else{
goto Error3;
}
Error4:
Person Custom1(bFirstName, bSurname, bGender, bAge, 100);
return 0;
}
but if in the confirmation system I say I want to make a new one the goto function will work but asking for the first name will not work and it will immediately go to asking for the surname
and at the end when it asks if i'm fine with the attributes first name will be empty.
I recommend using loops for error correction and functionality continuations:
bool continue_program = true;
while (continue_program)
{
//...
std::cout << "Continue program (Y/N)?";
char response;
std::cin >> response;
response = tolower(response);
if (response != 'y') continue_program = false;
}
You can also use do-while for error correction:
int value = 25;
do
{
std::cout << "Enter the number 5: ";
std::cin >> value;
} while (value != 5);
This should eliminate a lot of your gotos.
I have solved the problem-I have got rid of goto's but that wasn't the problem.
I made YesNo a string and then made Error correction a do while loop and at the end I had to ask-Using getline-for the input of YesNo twice in the code but it only asked once when running I still have no idea what the problem was but I have fixed it.

c++ Input Validation printing twice?

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;
}

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.

Unable to correctly both verify invalid input and accept correct range values with C++

I am an amateur practicing code in C++ and I cannot get my code to work correctly. I am hoping that someone can find my issue or point me in the correct direction.
I am simply trying to create a switch/case menu for users to select from. I would like them to not be able to enter any incorrect values as input. the only correct values are 1,2,3 or 4. If there are any lower, greater, or non-numeric values entered I would like them to be stuck in a loop until they enter a correct value.
My issue with my working error check is that when they actually enter the correct values in they are still stuck in the loop?! I have tried rearranging my code, but then the error blows up my program again.
Thank you for any advice, code input, etc. I have no idea why it is not working!!!
And on a related note. I was having issues getting my jgrasp download to work correctly for c++ so i downloaded a compiler called code::block. for some reason it cannot register the system("") commands?! any ideas or a better compiler would be appreciated. thanks. oh and here is my code for my first issue... after the code is where my switch/case menu begins. thank you for any help
int main()
{
string name;
int ans2, ans3, count = 0, extra, select = 1, arraycount = 0, choice;
bool flag = true;
cout << "Hello World" << endl;
cout << "Enter your name: ";
cin >> name;
cout << "Thank you for using this program " + name << endl;
while (select != 4)
{
cout << "MAIN MENU\n";
cout << "Please enter a corrisponding numeric for your selection.\n";
cout << "1. You are Michael...\n";
cout << "2. You are Tim\n";
cout << "3. You are someone else\n";
cout << "4. Program exit\n";
cout << "Enter your selection: ";
cin >> select;
do
{
while(!(cin >> select))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You entered: " << select << endl;
if (select != 1 && select != 2 && select != 3 && select != 4)
{
flag = false;
cout << "Error. Please enter a valid selection.";
cout << "Enter your selection";
cin >> select;
}
else
flag = true;
}while(flag == false);
cout << "\n\nThank you for your choice\n";
//system("pause");
//system("cls");
this part of your code ,
if (select != 1 && select != 2 && select != 3 && select != 4)
{
flag = false;
cout << "Error. Please enter a valid selection.";
cout << "Enter your selection";
cin >> select;
}
this part may be the cause of your problem as you input the select once again here, but you don't modify the flag value. You could add the check to while(!(cin >> select)) as
while(!(cin >> select) || select > 4 || select < 1)

C++ if statement in function

So I am trying to write a basic program that will keep track of a balance, and you can make a withdraw, make a deposit, and quit the program altogether. This is the code.
#include <iostream>
#include <string>
using namespace std;
double balance = 0, withdraw = 0, deposit = 0;
string choice;
class Bank
{
public:
void withdrawMoney()
{
if(balance - withdraw >= 0)
{
balance = balance - withdraw;
}
else
{
cout << "$5 penalty for attempting to withdraw more than you have.";
balance -= 5;
}
}
public:
void depositMoney()
{
balance = balance + deposit;
}
};
int main()
{
Bank bankObject;
cout << "Welcome to the Bank Program!" << endl;
while(true)
{
cout << "Would you like to make a withdrawal, a deposit, or quit the program: ";
cin >> choice;
if(choice.compare("withdrawal") == 0)
{
cout << "Please enter the amount to withdraw: ";
cin >> withdraw;
bankObject.withdrawMoney();
cout << "New balance is: $" << balance << endl;
}
else if(choice.compare("deposit") == 0)
{
cout << "Please enter the amount to deposit: ";
cin >> deposit;
bankObject.depositMoney();
cout << "New balance is: $" << balance << endl;
}
else if(choice.compare("quit") == 0)
{
break;
}
else
{
cout << "Invalid input." << endl;
}
cout << "Would you like to try again or quit: ";
cin >> choice;
if(choice.compare("quit") == 0)
{
break;
}
}
cout << "Thank you for using the Bank Program." << endl;
return 0;
}
I am new to C++, (I started today), but I have previous experience with Java. I am continually getting an error at the withdraw method, at the first if statement, saying that I have an invalid use of the member function. Any help would be appreciated. Also, not sure if it matters, but I am using the IDE Code::Blocks.
EDIT: First problem fixed, but now there is another, when I run the code, I can get through it once just fine, but when I try to go through a second time by typing try again, it gets stuck in a loop and answers the first question as "incorrect input". Help?
You use withdraw as both a global variable and a method name. Renaming one of them should fix this particular error.
Edit: When you type "try again", your program only reads "try" (because the default is to break up the input by whitespace), leaving "again" in the buffer for the next read from cin. You can verify that with a few debugging output statements.