c++ getline function does not let me input - c++

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.

Related

C++ Switch Statment Exception Handling

I am trying to code exception handling in my switch statement for a memnu in case user inputs something other than an int. Tried many different methods and still get continuous loop when user inputs a character.
I have tried using std exception but even with the include my compiler still sees error during build.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
class Exam
{
public:
int loadExam()
{
//ifstream infile;
//string examName = exam;
ifstream infile("exam.txt");
streambuf *cinbuf = cin.rdbuf(); //save old buf
cin.rdbuf(infile.rdbuf()); //redirect std::cin to infile.txt!
string line, theQuestion, questiontype, theAnswer;
int questionvalue;
//get the number of questions from the first line in the file
getline(cin,line);
numquestions = atoi(line.c_str());
for(int count = 0; count < numquestions; count++){
getline(cin,line);
//get the next line with the question type and the value of the question
int npos = line.size();
int prev_pos = 0;
int pos = 0;
while(line[pos]!=' ')
pos++;
questiontype = line.substr(prev_pos, pos-prev_pos);
prev_pos = ++pos;
questionvalue = atoi(line.substr(prev_pos, npos-prev_pos).c_str()); // Last word
//process a true/false question
if (questiontype == "TF")
{
myQuestions[count] = new QuestionTF;
getline(cin,theQuestion);
myQuestions[count]->setQuestion(theQuestion,questionvalue);
}
//process a multiple choice question
if (questiontype == "MC")
{
myQuestions[count] = new QuestionMC;
getline(cin,theQuestion);
myQuestions[count]->setQuestion(theQuestion,questionvalue);
}
}
cin.rdbuf(cinbuf); //restore cin to standard input
return numquestions;
}
void displayExamQuestions(int numquestions)
{
string qtype;
//print out the questions that have been processed
for(int count = 0; count<numquestions;count++)
{
qtype = myQuestions[count]->getQuestionType();
cout << qtype << " " << myQuestions[count]->getValue() << "\n";
myQuestions[count]->printOptions();
cout << "\n";
}
}
private:
Question *myQuestions[10];
int numquestions;
};
int main() {
Exam myExam;
int numquestions;
int choice;
while((choice = displayMenu())!=3)
switch(choice)
{
case 1:
numquestions = myExam.loadExam();
break;
case 2:
myExam.displayExamQuestions(numquestions);
break;
default:
cout << "Invalid choice. Try again.\n\n";
}
getchar();
return 0;
}
int displayMenu()
{
int choice;
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam "<<endl;
cout << "\t2. Display Exam "<<endl;
cout << "\t3. Quit"<<endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
cin >> choice;
cout << "\n" << endl;
return choice;
}
Require output to read "Invalid selection, Please try again" when a user inputs a character or string of alpha characters.
In this case, validation should be handled by the displayMenu function for two reasons.
The displayMenu function says that it will return an integer so it should be responsible for ensuring the user inputs a number, not a char or string.
The displayMenu lists the options so it knows how many options are available, meaning it should also check that the integer is between 1 and 3.
Infinite loop with cin when typing string while a number is expected
int displayMenu() //This function should be responsible for validating that an
// int was inputed
{
int choice;
while (true)
{
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam " << endl;
cout << "\t2. Display Exam " << endl;
cout << "\t3. Quit" << endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
cin >> choice;
cout << "\n" << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //This clears out the stream if they entered a string
//Try using cin.ignore() and inputing a string to see what happens.
}
else if (choice >= 1 && choice <= 3)
{
break;
}
}
return choice;
}
You could decouple this second part by having a displayMenu function that simply prints the menu and a second function called getInput that doesn't care what integer is inputed. It would then be up to the calling function to make sure the value is between 1 and 3.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
void displayMenu();
int getInput();
int main() {
int numquestions;
int choice = 0;
while (choice != 3)
{
displayMenu();
while ((choice = getInput()) < 1 || choice > 3)
{
std::cout << "Please pick a value between 1 and 3\n";
displayMenu();
}
switch (choice)
{
case 1:
cout << "Case 1\n";
break;
case 2:
cout << "Case 2\n";
break;
default:
cout << "Invalid choice. Try again.\n\n";
}
}
getchar();
return 0;
}
//Only responsible for getting an int
int getInput()
{
int choice;
while (true)
{
cin >> choice;
cout << "\n" << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
std::cout << "Please enter a valid number\n";
}
else
{
break;
}
}
return choice;
}
//This function only displays a menu
void displayMenu()
{
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam " << endl;
cout << "\t2. Display Exam " << endl;
cout << "\t3. Quit" << endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
}

cin.getline() isn't working with switch statement

I've been trying to work on a program for class but for some reason when i input the number one for the program it goes to case 1 but then it doesn't let me enter a string and goes straight back to the menu. Ex) enter in 1 the result is: Enter a string: 01. Adds number but ignores anything that not a number.
If I use a regular cin statement the code will execute perfectly fine. I don't understand why it is doing this. Can somebody help?
#include <iostream>
#include <cctype>
using namespace std;
void firstChoice(char []);
int main()
{
int choice;
int answer;
const int SIZE = 100;
char line[SIZE];
do
{
cout << "1. Adds numbers but ignores anything thats not a number." << endl;
cout << "2. Count the number of consonants in a string." << endl;
cout << "3. Counts the vowels in a string." << endl;
cout << "4. Counts whitespace characters in a string." << endl;
cout << "Enter a number to access that program or 0 to end it: ";
cin >> choice;
switch(choice)
{
case 1:
cout << "\nEnter a string: ";
cin.getline(line, SIZE);
firstChoice(line);
break;
case 2:
cout << "Enter a string: ";
cin.getline(line, SIZE);
break;
case 3:
cout << "Enter a string: ";
cin.getline(line, SIZE);
break;
case 4:
cout << "Enter a string: ";
cin.getline(line, SIZE);
break;
}
}
while(choice != 0);
return 0;
}
void firstChoice(char line[])
{
int size2 = 0;
int sum = 0;
while(line[size2] != '\0')
{
if(isalpha(line[size2]))
{
line[size2] = 0;
}
sum += line[size2];
size2++;
}
cout << sum;
}
After this statement
cin >> choice;
use
#include <limits>
//...
cin >> choice;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

C++ Pulling information and looping to display

Not under standing looping for arrays. Looping through all of grab some or search. Can someone explain the process? Thanks in advance. Sorry if duplicate. I looked around and couldnt find a solid explaination that I could understand.
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void allContacts(string names[], string phones[])
{
cout << "Showing all contacts... Press Q to go back to main menu" << endl;
}
void addName(string names[], string phones[])
{
bool keepGoing;
string input;
beginning:
for (int i = 0; i < sizeof(names); i++)
{
cout << "Enter contact name: ";
cin >> names[i];
cout << "Enter contact number: ";
cin >> phones[i];
cout << "Do you have another contact to add? y or no" << endl;
cin >> input;
if(input == "y" || input == "Y")
{
goto beginning;
}
if(input == "n" || input == "N")
{
cout << "Contacts you have entered: " << endl;
cout << names[i] << " : " << phones[i] << endl;
}
}
}
void searchName(string names[], string phones[])
{
string name;
cout << "Enter Name: ";
cin >> name;
cout << "Search for a name or Press Q to go back to main menu" << endl;
for (int i = 0; i < sizeof(names); i++){
if (name == names[i])
{
cout << counter << names[i] << " 's phone number is: " << phones[i] << endl;
} else {
cout << "No results found";
}
}
}
int main()
{
string names[100];
string phones[100];
int choice;
cout << "============================" << endl;
cout << "=== Welcome to PhoneBook ===" << endl;
cout << "============================" << endl;
cout << "1- Add a New Contact" << endl;
cout << "2- Search By Name" << endl;
cout << "3- Display All" << endl;
cout << "0- Exit" << endl;
cout << "Select a number: " << endl;
cin >> choice;
switch(choice)
{
case 1:
addName(names, phones);
break;
case 2:
searchName(names, phones);
break;
case 3:
allContacts(names, phones);
break;
case 0:
cout << "Exiting PhoneBook...";
break;
}
}
In C++ arrays lose attributes when passed to functions. Those attributes are capacity and size (number of filled slots). You will need to pass this additional information for each array:
void addName(string names[], unsigned int names_capacity, unsigned int names_size,
string phones[], unsigned int phones_capacity, unsigned int phones_size)
To get around this, you can use std::vector. The std::vector knows its capacity and size, so you don't have to pass additional attributes to your function.
Also, if you use tolower or toupper before you compare, you only need to make one comparison:
char input;
cout << "Do you have another contact to add? y or n" << endl;
cin >> input;
input = toupper(input);
if(input == 'Y')
When using strings, you can convert them to all uppercase or all lowercase by using std::transform, such as:
std::transform(input.begin(),
input.begin(), input.end(),
tolower);

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.

Get blank line after calling Palindrome function

So I have these two functions at the top of my program:
string deletespaces(string sentence){
sentence.erase(std::remove(sentence.begin(), sentence.end(), ' '), sentence.end());
return sentence;
}
and
string checkpalindrome(string sentence){
deletespaces(sentence);
if (sentence == string(sentence.rbegin(), sentence.rend())){
cout << sentence << " is a palindrome." << endl;
}
if(sentence != string(sentence.rbegin(), sentence.rend())){
cout << sentence << " isn't a palindrome." << endl;
}
}
This is my main body of code.
int main(){
int x = 1;
string originalsentence;
while (x == 1) {
int a = 1;
int input;
string sentence;
cout << "Press 1 to reverse a string, 2 to check a palindrome, and anything else to quit: ";
cin >> input;
if(input == 1) {
cout << "Enter a sentence to reverse: ";
cin.ignore();
getline(cin,originalsentence);
originalsentence = sentence;
cout << string(sentence.rbegin(), sentence.rend()) << endl;
}
if(input == 2) {
cout << "Enter a sentence to check: ";
cin.ignore();
getline(cin,originalsentence);
originalsentence = sentence;
checkpalindrome(sentence);
}
cout << "Hit 1 if you want to continue, anything else to quit: ";
cin >> x;
}
}
So here is my problem. I am able to put in my choice about whether to reverse a string or check whether the string is a palindrome. However, when I try to reverse the string, it simply gives a blank line, then asks whether I want to continue. When I ask to check a palindrome, it simply says "is a palindrome" regardless of what I input. Any ideas?