Code to get user input not executing/skipping in C++ - 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.

Related

c++ While loops prints the couts twice

In my code, the while loop prints the cout twice when it should print it once, as well as the function's couts. I don't understand why it's doing this - it is supposed to display
What would you like to do?
Deposit
Withdraw
Cancel
But, it displays that twice.
while (yesNo == 'Y') {
cout << "What would you like to do?"
<< endl
<< endl;
menu();
getline(cin, bankChoice);
if (bankChoice == "Withdraw")
{
withdrawTotal = withdraw(bankAmount);
bankAmount = withdrawTotal;
cout << "You now have $"
<< bankAmount
<< " in your account."
<< endl;
cout << "Would you like to do anything else?"
<< endl
<< "Y/N: ";
cin >> yesNo;
}
if (bankChoice == "Deposit")
{
depositTotal = deposit(bankAmount);
bankAmount = depositTotal;
cout << "You now have $"
<< bankAmount
<< " in your account."
<< endl;
cout << "Would you like to do anything else?"
<< endl
<< "Y/N: ";
cin >> yesNo;
}
if (bankChoice == "Cancel") {
return 0;
}
}
That is the loop I am using. If additional code is needed I can post it as well, but this is the part that is causing the issue. I've tried the code without it and it works fine, but I'd like to get the code to loop until the user enters 'N'.
You are using both std::getline and operator>> to read from std::cin. operator>> does not consume the trailing newline, so the next call to std::getline() will immediately read the following newline and interpret it as an empty line of text that was entered. This will run through the loop, and go back up to the top, for the second prompt.
Never use operator>> with std::cin when you intend to read a single line of text.
The following short example demonstrates this point:
#include <iostream>
#include <string>
int main()
{
char c;
std::string l;
std::cin >> c;
std::cout << "A line of text please: ";
std::getline(std::cin, l);
}
Run it, enter "Y", and try to figure it out, yourself, why the program terminates immediately.
Once again: don't use operator>> to read lines of text from std::cin. It is a recipe for grief, and bugs.
In addition to Sam's answer, I'd like to recommend that you extract common functionality outside your two if statements:
std::string yesNo;
while (yesNo.compare("Y") == 0) {
cout << "What would you like to do?"
<< endl
<< endl;
menu();
getline(cin, bankChoice);
if (bankChoice == "Cancel")
return 0;
if (bankChoice == "Withdraw") {
withdrawTotal = withdraw(bankAmount);
bankAmount = withdrawTotal;
}
if (bankChoice == "Deposit") {
depositTotal = deposit(bankAmount);
bankAmount = depositTotal;
}
cout << "You now have $"
<< bankAmount
<< " in your account."
<< endl;
cout << "Would you like to do anything else?"
<< endl
<< "Y/N: ";
std::getline(std::cin, yesNo);
}

C++ loop error that my professor can't figure out

I am currently taking a C++ programming class and am working on a project in which I have to create a fairly simple movie database. My code essentially works as intended yet in certain cases it causes the main menu to loop infinitely and I cannot figure out why. I brought this to my teacher and he cannot explain it either. He gave me a workaround but I would like to know if anyone can see the cause of the problem. Full code is as follows:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct MovieType
{
string title;
string director;
int year;
int length;
string rating;
};
MovieType addMovie() {
MovieType newMovie;
cout << "Movie title :";
getline(cin, newMovie.title);
cout << "Director :";
getline(cin, newMovie.director);
cout << "Year :";
cin >> newMovie.year;
cout << "Length(in minutes) :";
cin >> newMovie.length;
cout << "Rating :";
cin >> newMovie.rating;
cout << endl;
return newMovie;
}
void listMovie(MovieType movie) {
cout << "______________________________________" << endl;
cout << "Title : " << movie.title << endl;
cout << "Director : " << movie.director << endl;
cout << "Released : " << movie.year << endl;
cout << "MPAA Rating : " << movie.rating << endl;
cout << "Running time : " << movie.length << " minutes" << endl;
cout << "______________________________________" << endl;
}
void search(vector<MovieType> movieVector) {
string strSearch;
cout << endl << "Search title: ";
getline(cin, strSearch);
for (int c = 0; c < movieVector.size(); c++) {
if (movieVector.at(c).title == strSearch)
listMovie(movieVector.at(c));
}
}
int main() {
bool quit = 0;
vector<MovieType> movieVector;
while (quit == 0) {
char selection = 'f';
cout << "Main Menu:" << endl;
cout << "'a' - Add movie" << endl;
cout << "'l' - List movies" << endl;
cout << "'s' - Search by movie title" << endl;
cout << "'q' - Quit" << endl;
cout << "Please enter one of the listed commands:";
cin >> selection;
cin.ignore();
cout << endl;
if (selection == 'a')
movieVector.push_back(addMovie());
else if (selection == 'l') {
for (int c = 0; c < movieVector.size(); c++) {
listMovie(movieVector.at(c));
}
}
else if (selection == 's') {
search(movieVector);
}
else if (selection == 'q')
quit = 1;
}
return 0;
}
When an unexpected input type is entered during the addMovie function(like entering text for the int type year), it just runs through the function then loops through the menu infinitely. It appears to me that the code just stops even looking at the input stream. I have tried using cin.ignore() in many different places but it doesn't matter if there is nothing left in the stream it just keeps going.
I am using NetBeans to compile my code.
I really have no idea why it behaves like this otherwise I would offer more information but I am just curious as to why this happens, because as I said before, my professor doesn't even know why this is happening.
Any help or insight is greatly appreciated.
cin enters an error state where cin.fail() is true. In this state it just ignores all input operations. One fix is to clear the error state, but better, only use getline operations on cin, not formatted input.
E.g., instead of
cin >> newMovie.year;
… do
newMovie.year = stoi( line_from( cin ) );
… where line_from can be defined as
auto line_from( std::istream& stream )
-> std::string
{
std::string result;
if( not getline( stream, result ) )
{
// Throw an exception or call exit(EXIT_FAILURE).0
}
return result;
}
Disclaimer: code untouched by compiler.

Won't let me read in user input in after IF statement (homework)

I am having some issues with my simple code of creating a dvd & software list to import into a csv file.
I have the output working fine but for some reason my program is skipping my first part of the code. If I take out the IF statement, that bit of code works so I am not understanding why.
my output looks like this:
Would you like to add new media? Enter M for Movie or S for software: m
Enter the name of the Movie (20 Chararters or less)Name: Enter a rating for
your movie 1-5:
I am not getting any errors in my compiler (Visual Studio 2013) and it does not allow me to input a name and skips right to rating.
Any explanations or suggestions would be appreciated as I want to fix this before I move on to adding more.
here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
string typeM = "movie";
string typeS = "software";
char answer, mediainput;
int rating = 0;
string dir, type;
string moviename,softname;
do
{
cout << "Would you like to add new media? Enter M for Movie or S for software: ";
cin >> mediainput;
cout << endl;
if (mediainput == 'm' || mediainput == 'M')
{
cout << "Enter the name of the Movie (20 Chararters or less) \n Name: ";
getline(cin, moviename);
cout << endl;
cout << "Enter a rating for your movie " << moviename << " 1-5 ";
cin >> rating;
if (rating < 1 || rating > 5)
{
cout << "You must enter a number from 1 to 5. Enter a number rating: ";
cin >> rating;
cout << endl;
}
ofstream outdata("DVD_Software_inventory.csv", ios_base::app);
outdata << moviename << "," << typeM << "," << rating << "," << endl;
outdata.close();
}
if (mediainput == 's' || mediainput == 'S')
{
cout << "Enter the name of the software (20 Chararters or less) \n Software name: " << endl;
getline(cin, softname);
cout << "Enter the directory it is in \n Directory: ";
cin >> dir;
ofstream outdata("DVD_Software_inventory.csv", ios_base::app);
outdata << softname << "," << typeS << ",," << dir << "," << endl;
outdata.close();
}
cout << "\n\nWould you like to add more? Y/N ";
cin >> answer;
cout << endl;
if (answer == 'N' || answer == 'n')
{
cout << "** End of Program **" << endl;
break;
}
} while (answer == 'Y' || answer == 'y');
system("pause");
return(0);
}
The problem is that while your cin >> statement ignores "\n" (the newline character), the character is still in cin's buffer. getline(), however,
does not ignore the "\n" character.
The solution, therefore, is to explicitly tell cin to ignore the "\n" character:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
getline(cin, moviename);
(credit to http://www.cplusplus.com/forum/beginner/24470/)

c++ getline function does not let me input

So i have a palindrome program and here are the codes:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void palindrome();
void compareTwoInt();
bool validation(const string&);
int main()
{
int selection;
cout << "\t\t\t MENU\n";
cout << "\t\t\t ----\n";
cout << "\t\t\t1. Palindrome";
cout << "\n\t\t\t2. Compare Two Integers";
cout << "\n\t\t\t3. End program\n";
cout << "\n\t\t\tEnter your choice : ";
cin >> selection;
while (selection < 0 || selection > 4)
{
cout << "\t\t\nInvalid entry. Please enter an appropriate entry.";
cout << "\n\n \t\t\tEnter your choice: ";
cin >> selection;
}
if (selection == 1)
{
cout << "Enter a word, phrase, sentence: \n";
string input;
getline(cin, input);
string input2;
for (unsigned int i = 0; i < input.length(); i++)
{
if (isalnum(input[i]))
{
input2 += toupper(input[i]);
}
}
cout << input2 << endl;
if (validation(input2))
{
cout << "The phrase is a palindrome!" << endl;
cout << "Press <Enter> key back to menu" << endl;
}
else
{
cout << "The phrase is not a palindrome!" << endl;
cout << "Press <Enter> key back to menu" << endl;
}
fflush(stdin);
cin.get();
system("cls");
return main();
}
else if (selection == 2)
{
compareTwoInt();
fflush(stdin);
system("cls");
return main();
}
else if (selection == 3)
{
cout << "\t\t Good Bye. Press <Enter> key to End the program.\n";
}
fflush(stdin);
cin.get();
return 0;
}
void compareTwoInt()
{
int first, second;
cout << "\n\nEnter your positive integer : ";
cin >> first;
cout << "\nEnter your positive integer : ";
cin >> second;
fflush(stdin);
cin.get();
}
bool validation(const string& input)
{
return input == string(input.rbegin(), input.rend());
}
for some reason when i choose 1 for the palindrome, it doesn't let me write the words, (in another words, it doesn't let me input)
the console just says:
Enter a word, phrase, sentence:
The phrase is palindrome!
Press key back to menu
Anybody have an idea how to fix this?
Thanks in advance!
When you choose 1 for the palindrome, you hit enter. Thus your input consists of the number 1 followed by a newline. Your cin >> selection; reads the number 1 and then your getline(cin, input); reads the newline, which it interprets as an empty line. You have written no code to do anything sensible with the newline character input after the number, so nothing sensible happens.
Try typing 1foof<enter> instead. Your code will read that as a 1 followed by a line containing foof.

Why is my If/Else statment block not executing completely?

I'm doing a simple project for my CS class. The goal is to have a person input the amount of each fruit (apples, bananas, oranges) they are purchasing, and the program calculates the total and presents an invoice at the end. My Professor wants us to also include an input check, to verify that the input is a number between 0 and 100. to do this, I have this section of code.
string name;
int apples, oranges, bananas;
int FRUIT_MAX = 100;
int FRUIT_MIN = 0;
float appleCost, orangeCost, bananaCost,
subTotal, tax, total;
cout << "Welcome to Bob's Fruits, what is your name..." << endl;
getline(cin, name);
cout << "How many apples would you like" << endl;
cin >> apples;
cout << endl;
//checking if user entered a number for apples
if (apples >= FRUIT_MIN && apples <= FRUIT_MAX)
{
cout << "Thanks" << endl;
}
else //makes the user retype entry if invalid
{
cout << "Please input a number thats 0 or greater than 0. " << endl;
cin >> apples;
cout << endl;
}
cout << "How many oranges would you like" << endl;
cin >> oranges;
if (oranges >= FRUIT_MIN && oranges <= FRUIT_MAX) //checking to see if number is good
cout << "Thanks" << endl;
else //makes the user retype entry if invalid
{
cout << "Please input a number thats 0 or greater than 0." << endl;
cin >> oranges;
cout << endl;
}
cout << "How many bananas would you like" << endl;
cin >> bananas;
if (bananas >= FRUIT_MIN && bananas <= FRUIT_MAX)
cout << "Thanks";
else
{
cout << "Please input a number thats 0 or greater than 0.";
cin >> bananas;
cout << endl;
}
When I enter a value between 0-100, I receive the proper "thanks" output and then it moves on to the next question. When I enter a number outside of 0-100, the else statement triggers sucsessfully, and the program asks for a number between 0-11.
The problem is when a letter is input. If a letter is input, the program skips through every remaining line, ignoring any additional cin commands, and displays the formatted invoice with all negative numbers. Any ideas why this is happening?
When cin gets an invalid value, it sets a failbit.
int n;
cin >> n;
if(!cin)
{
//not a number, input again!
}
You need to use cin.ignore() so that the input will be 'reset' and request the input again.
you can change the cin part into
while (!(cin>>apples)) {
cout<<"Type Error"<<endl;
cin.clear();
cin.sync();
}
The Problem ist that you do not check for proper type of your input.
Your apples variable is an Int. So as long as a user enters an Int everything will be fine.
But what happens if he or she enters a Char ?
The answer is as one of the guys before me mentioned is that the cin operation will fail.
What can you do to prevent or better to say handle this situation:
#include<iostream>
using namespace std;
int main(int argc , char** argv) {
int apples = 0; //Its always good to initialise a var with a value
cout << "Please enter a number: " << endl;
cin >> apples;
if(!cin) {
cout << "Not a number!" << endl;
// Handle the error
}
else {
cout << "A number was entered" << endl;
}
return 0;
}
Instead of checking for !cin you can also use cin.fail() which will be true if the last cin operation failed.
If you want to read more about cin or inputstreams in generell I would advise you to take a look at the C++ reference.