issue with c++ code skipping get line statement - c++

Hey guys i am having an issue with an assignment I am working on.
The code is as follows:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
class payroll
{
private:
char empnum[10];
char empfirstname[150];
char emplastname[150];
char empsin[9];
char empdob[10];
char empphone [15];
char empstreet[100];
char empcity[60];
char empprovince[150];
char empcountry[200];
char empstatus[50]; //Employee status. EX: Terminated, On leave, Active etc.
int empsalaryei;
int empsalaryfedtax;
int empsalarycpp;
int empsalarynet;
int empsalarygross;
public:
void addrec(void);
void modrec(void);
void viewrec(void);
void exit(void);
};
payroll rec;
payroll emp;
ifstream inFile1;
ifstream inFile2;
bool check = false;
int main()
{
system("CLS");
char ch;
do
{
cout<<"1. Add an employee\n";
cout<<"2. Modify employee record\n";
cout<<"3. View employee record\n";
cout<<"0. Exit\n";
cout<<"Please choose an item: ";
if (check == true)
{
system("CLS");
ch=0;
}
else
cin>>ch;
switch(ch)
{
case '1':
emp.addrec();
break;
case '2':
emp.modrec();
break;
case '3':
emp.viewrec();
break;
case '0':
emp.exit();
return 0;
}
}while(ch !=0);
return 0;
}
void open_employee_info() //function to open employee data file
{
string filename1 = "employee-details.dat"; //define which file to open
inFile1.open(filename1.c_str()); //open our payroll file
if(inFile1.fail()) //if our file open fails....
{
cout << "\nSorry the file was not opened successfully"<< "\n Please check that the file does exist or create it" << endl;
exit(1);
}
cout << "\n The file was opened successfully" << endl;
}
void open_payroll_info() //function to open payroll salary information file
{
string filename2 = "payroll-info.dat"; //define file name
inFile2.open(filename2.c_str());
if(inFile2.fail())
{
cout << "\nSorry the file was not opened successfully"<< "\n Please check that the file does exist or create it" << endl;
exit(1);
}
cout << "\n The file was opened successfully" << endl;
}
void payroll::addrec(void) //Record adding
{
char userinputadd = ' ';
cout << "\nPlease Enter the Employee number: ";
gets(rec.empnum);
cout << "\nPlease Enter the Employee's First Name: ";
gets(rec.empfirstname);
cout << "\nPlease Enter the Employee's Last Name: ";
gets(rec.emplastname);
cout << "\nPlease Enter the Employee's Date of Birth (mmddyyyy): ";
gets(rec.empdob);
cout << "\nPlease Enter the Employee's Social Insurance Number: ";
gets(rec.empsin);
cout << "\nPlease Enter the Employee's Phone Number: ";
gets(rec.empphone);
cout << "\nPlease Enter the Employee's Address: ";
gets(rec.empstreet);
cout << "\nPlease Enter the Employee's City: ";
gets(rec.empcity);
cout << "\nPlease Enter the Employee's Province: ";
gets(rec.empprovince);
cout << "\nPlease Enter the Employee's Country: ";
gets(rec.empcountry);
cout<<"\nPlease Enter the Employee's Status: ";
gets(rec.empstatus);
cout << "\nPlease Enter the Employee's Weekly Gross Salary: ";
cin >> rec.empsalarygross;
cout<<"Would you like to return to the main menu?(y), else the program will exit: ";
cin>>userinputadd;
if (userinputadd =='y' || userinputadd =='Y')
main();
else
exit();
}
void payroll::modrec(void) //Record Modification
{
system("CLS");
int empmodnum=0;
check = false;
char userinputmod = ' ';
cout<<"\nEnter the employee number for the record you would like to modify: ";
cin>>empmodnum;
cout<<"Would you like to return to the main menu?(y), else the program will exit: ";
cin>>userinputmod;
if (userinputmod =='y' || userinputmod =='Y')
main();
else
exit();
}
void payroll::viewrec(void) //Record viewing
{
system("CLS");
check = false;
char userinputview = ' ';
cout<<"Would you like to return to the main menu?(y), else the program will exit: ";
cin>>userinputview;
if (userinputview =='y' || userinputview =='Y')
main();
else
exit();
}
void payroll::exit(void)
{
inFile1.close();
inFile2.close();
check = true;
}
So on the front menu if you hit 1 to add a record you will see it skips the first cin statement being employee number.
Does anyone have an idea why this would occur?

You are leaving the newline character in your input stream after you press 1.
Consider all of the keys that you are typing. If you type "1" for addrec, then an employee ID of 987, then the name "John", your input stream looks like this:
1, \n, 9, 8, 7, \n, J, o, h, n, \n
You read the first character with cin >> ch. The next input statement you have is gets().
gets() reads, correctly, all of the characters up to the next newline. Since you still have the newline that follows '1', that first line will be read as blank.
Try adding this somewhere to your program:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

You probably have a buffer issue so you need to flush stdin. Check google for details.

Related

C++ getline function continuous loop

I am trying to use a getline function in the following code, however it just enters an indefinite loop. Should I enter 1, it will then jump to the another iteration of the loop and ask for my menu choice again, rather than asking for my name.
Does anyone have any idea where I'm going wrong?
#include <iostream>
#include <string>
#include <ncurses.h>
using namespace std;
// DECLARE
void menu();
void menu_act_on_choice();
void string_function();
// CODE
void menu_act_on_choice(int choice_in) {
switch (choice_in) {
case 1:
string_function();
break;
default:
break;
}
}
void string_function() {
string user;
cout << "Enter your first and last: ";
getline(cin, user);
cout << user << endl;
}
void menu() {
int choice = 0;
do {
cout << "1. String functions" << endl;
cout << "2. Array functions" << endl;
cout << "3. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
menu_act_on_choice(choice);
} while(choice != 3);
}
//EXECUTE
int main() {
menu();
}
When you enter the menu choice which is read by
cin >> choice;
you ended that with the Enter key right?
That Enter key will be added to the input buffer as a newline. But cin >> choice will not read it, instead that happens with the getline call which reads it as an empty line.
The simple solution is to ignore all input until (and including!) the newline after getting the menu choice.
cin >> choice;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Add cin.ignore(); before getline line.

get line function in c++ not working as it should

I was trying to get the user input and it should include a space because I am asking for a full name. So I used the getline method but I can't input the data correctly.
Here's the code:
#include <iostream>
#include <string>
string name, mobile, landline, work;
cout << "Enter the name of the contact to be added:";
getline(cin, name);
cout << "Enter the mobile number of this contact:";
getline(cin, mobile);
cout << "Enter the landline number of this contact:";
getline(cin, landline);
cout << "Enter the work number of this contact:";
getline(cin, work);
When I run the program this is what I get:
Enter the name of the contact to be added:Enter the mobile number of this contact:
This is the main method:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: main.cpp
* Author: Gaby
*
* Created on March 25, 2020, 7:14 PM
*/
#include "Contact.h"
#include "DCSList.h"
#include <iomanip>
#include <fstream>
#include <sstream>
using namespace std;
void showMenu();
void saveChanges(ofstream& file, DCSList& list);
/*
*
*/
int main(int argc, char** argv) {
fstream file; //This is the file we read from
ofstream outputFile; //This is the file we will write on at the end
string name, numberString; //Strings to extract the data from the file
string numbers[3]; //string array of numbers
string numberExtracted; //Used to extract each number from the numberString
string numbOfContacts; //Number of Contacts we want to read from file
int number; //Integer variable of the parsed value of the number read
int counter = 1; //Number of contacts read from file
int choice = 0; //Choice of user
DCSList list;
file.open("./ContactList.txt");
if(file.is_open()){
//If file is open then read from it
//First get the number of contacts in list
getline(file, numbOfContacts);
//Convert the number in the file to an integer
stringstream count(numbOfContacts);
//Set the value of number
count >> number;
while(counter <= number){
//Extract the name of the contact
getline(file, name);
//Extract the mobile, work and home numbers
getline(file, numberString);
//We will need to split the numberString with the - as delimiter
stringstream ss(numberString);
int i = 0; //Counter for numbers
while(getline(ss, numberExtracted, '-')){
numbers[i] = numberExtracted;
i++;
}
//Create a Contact object and add the contact to the list
Contact c(name, numbers[0], numbers[1], numbers[2]);
list.addNode(c);
counter++;
}
//Write on the other file
outputFile.open("NewContactList.txt");
if (outputFile.is_open()){
list.start();
while(list.hasNext()){
outputFile << list;
list.operator ++();
}
}
else{
cout << "File not opened!" << endl;
}
outputFile.close();
}
else{
cout << "File is not opened!" << endl;
}
file.close();
do{
showMenu();
cin >> choice;
switch(choice){
case 1:{
list.start();
while(list.hasNext()){
cout << list;
list.operator ++();
}
break;
}
case 2:
{
string name, mobile, landline, work;
cout << "Enter the name of the contact to be added:";
getline(cin, name);
cout << "Enter the mobile number of this contact:";
getline(cin, mobile);
cout << "Enter the landline number of this contact:";
getline(cin, landline);
cout << "Enter the work number of this contact:";
getline(cin, work);
//Create a contact object
Contact contact(name, mobile, work, landline);
//Add contact to list
list.addNode(contact);
}
break;
case 3:
{
string contactToDelete;
cout << "Enter a contact name or "
"any mobile, work, land number :";
cin >> contactToDelete;
if (list.deleteNode(contactToDelete)){
cout << "Contact has been deleted!" << endl;
}
}
break;
case 4:
{
string searchCriteria;
cout << "Enter a contact name or "
"any mobile, work, land number :";
getline(cin, searchCriteria);
if (list.searchNode(searchCriteria)){
cout << list;
}
else{
cout << "No contact found!" << endl;
}
break;
}
case 5:
{
cout << "Thank you for using the program." << endl;
cout << "All changes applied will be "
"saved to the output file" << endl;
//Write on the other file
outputFile.open("NewContactList.txt");
if (outputFile.is_open()) {
list.start();
while (list.hasNext()) {
outputFile << list;
list.operator++();
}
} else {
cout << "File not opened!" << endl;
}
file.close();
return 0;
}
default:{
cout << "Please enter a valid value to do an operation!" <<endl;
break;
}
}
}while(choice != 1 || choice != 2 ||
choice != 3 || choice != 4 || choice != 5);
return 0;
}
void showMenu(){
cout << "-------------PHONEBOOK-------------" << endl;
cout << "Enter a number according to "
"the operation you want to do: " << endl;
cout << "1. Show phone book" << endl;
cout << "2. Add new contact" << endl;
cout << "3. Delete a contact" << endl;
cout << "4. Search for a contact" << endl;
cout << "5. Exit program" << endl;
}
I am not able to input each value individually.
Do you know how can I fix this problem?
Thank you for your help.
How #NathanOliver has suspected you used a cin. In your main method in lines 111 and 153 (if formated in the same way as above) you can find them. Try to change them to getline() too. That should work.

How do I save passwords and usernames to a .txt file in c++. I still want to be able to retrieve them if the user tries to login

I'm starting a console based online bank(for fun). I was wondering how I would save usernames and passwords of people registering an account(perhaps a .txt file?). I was also wondering how I would go about checking the .txt file for the username and password when they attempt to log in. Any help is appreciated. Here is the source code
#include <iostream>
#include <conio.h>
#include <Windows.h>
#include <string>
#include <stdlib.h>
using namespace std;
bool gameOver;
// global variables
string EntryChoice;
int numberOfIncorrect = 5;
string NewUsername;
string NewPassword;
string LoginUsername;
string LoginPassword;
string NewFirstName;
string LoginFirstName;
string NewLastName;
string LoginLastName;
int Newage;
string Newgender;
int Loginage;
string LoginGender;
//declaration of functions
void Login();
void SignUp();
void BankCheck();
void BankError();
void Bank()
{
cout << "Welcome to the Bank of National Arabs\n";
cout << "-------------------------------------\n";
cout << "|To Sign Up type (Register) then Press Enter|\n";
cout << "|To Login type (Login) then Press Enter|\n";
cin >> EntryChoice;
BankCheck();
}
void BankCheck()
{
if (EntryChoice == "Login" || EntryChoice == "LOGIN" || EntryChoice == "login")
{
Login();
}
else if (EntryChoice == "REGISTER" || EntryChoice == "register" || EntryChoice == "Register")
{
SignUp();
}
else
{
system("cls");
BankError();
}
}
void BankError()
{
if (numberOfIncorrect == 1)
{
exit(1);
}
numberOfIncorrect -= 1;
cout << "Welcome to the Bank of National Arabs\n";
cout << "-------------------------------------\n";
cout << "|To Sign Up type (Register) then Press Enter|\n";
cout << "|To Login type (Login) then Press Enter|\n";
cout << "|ERROR| " << numberOfIncorrect << " Tries Left >> ";
cin >> EntryChoice;
BankCheck();
}
void Login()
{
system("cls");
cout << "Bank of United Arabs Login Page\n";
cout << "-------------------------------\n";
cout << "Username: ";
cin >> LoginUsername;
cout << "\nPassword:";
cin >> LoginPassword;
}
void SignUp()
{
system("cls");
cout << "Welcome to the Register Page\n";
cout << "----------------------------\n";
cout << "Age: ";
cin >> Newage;
cout << "\nGender: ";
cin >> Newgender;
cout << "\nFirst name";
cin >> NewFirstName;
cout << "\nLast Name";
cin >> NewLastName;
cout << "\nUsername: ";
cin >> NewUsername;
cout << "\nPassword";
cin >> NewPassword;
}
int main()
{
Bank();
return 0;
}
Yes, you can do so. Probably, everytime you input data from the user while registering, you can simultaneously store it into a txt file using c++ file operators(Read this : https://www.bogotobogo.com/cplusplus/fstream_input_output.php ), followed by a delimiter to mark the end of each individual record.
Keep the format in the text file as :
UserID1
Username1
Password1#
UserID2
Username2
Password2#
Here # is a delimiter.
For retrieving the records search for the username or id in the .txt file by reading records using the above delimiter. If the record is found, separate the record values by line and store them in a variable and then compare with the input data values. Continue searching till the EOF flag is false.

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.

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.