Code not allowing user input in strings after first string - c++

I have looked around and can't seem to find an answer to this. I am new to C++ and am attempting to write a program for a class that asks the user for the first and last names of 4 students and their ages. The program will then display the input names and ages and also display the average of the ages.
The issue I am having is that the program allows for input of the first name and age but then skips over the remaining three name input fields and only allows for the remaining three ages to be input.
I apologize if this ends up being a dumb question but I really am at a loss. Any help will be greatly appreciated.
Here is the code I have thus far:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string studentname1;
cout << "Please enter the first student's full name:" << endl;
getline(cin, studentname1);
int age1;
cout << "Please enter the first student's age:" << endl;
cin >> age1;
string studentname2;
cout << "Please enter the second student's full name:" << endl;
getline(cin, studentname2);
int age2;
cout << "Please enter the second student's age:" << endl;
cin >> age2;
string studentname3;
cout << "Please enter the third student's full name:" << endl;
getline(cin, studentname2);
int age3;
cout << "Please enter the third student's age:" << endl;
cin >> age3;
string studentname4;
cout << "Please enter the fourth student's full name:" << endl;
getline(cin, studentname2);
int age4;
cout << "Please enter the fourth student's age:" << endl;
cin >> age4;
cout << "Hello from our group." << endl;
cout << "NAME AGE" << endl;
cout << studentname1 << " " << age1 << endl;
cout << studentname2 << " " << age2 << endl;
cout << studentname3 << " " << age3 << endl;
cout << studentname4 << " " << age4 << endl;
cout << "The average of all our ages is: " << (age1 + age2 + age3 + age4) / 4.00 << endl;
return 0;
}

Since the age variables are int, the cin >> age1; will leave the newline character in the input stream. When next you call getline(), you will get the remainder of that line - which is empty, and so on.
Also, you have a copy-paste bug in your code. getline(cint, studentname2); is run for students 2, 3 and 4.
You can either solve the problem by using getline() for all input:
string agestring;
getline(cin, agestring)
stringstream(agestring) >> age1;
or clear cin when you're done reading the age:
cin >> age1;
cin.ignore();

Related

Use of getline to read a string with white spaces in a structure

I want to read strings with white spaces into members of a structure. Tried using getline but both the output statements are clubbed with a single cin for both. As per the similar posts here, tried using cin.ignore, but the input is not read into the member of the structure. Pls help. It's a part of my assignment and I'm a beginner in C++. This is how my code looks like:
#include <string.h>
using namespace std;
struct book {
string title, author;
int no_of_pages, year;
float price;
};
int main() {
int N;
cout << "Enter the no. of books whose details are to be entered:" << endl;
cin >> N;
book b[N];
int x;
for (x = 0; x < N; x++) {
cout << "Enter the title of book #" << x + 1 << ":" << endl;
getline(cin, (b[x].title));
// cin.ignore();
cin.ignore(1000, '\n');
cout << "Enter the author's name:" << endl;
getline(cin, (b[x].author));
cout << "Enter the no. of pages:" << endl;
cin >> b[x].no_of_pages;
cout << "Enter the price of book:" << endl;
cin >> b[x].price;
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
}
for (x = 0; x < N; x++) {
cout << "\n\n";
cout << "The details of book" << x + 1 << " are:" << endl;
cout << "Title :" << b[x].title << endl;
cout << "Author :" << b[x].author << endl;
cout << "No. of pages :" << b[x].no_of_pages << endl;
cout << "Price :" << b[x].price << endl;
cout << "Publishing year:" << b[x].year << endl;
cout << "---------------------------------------------";
}
return 0;
}
There's no point in using cin.ignore() in between two calls to getline. ignore is used to discard remaining characters after numeric input. So the place to use it is after numeric input and before the next getline. Like this
cout << "Enter the title of book #" << x + 1 << ":" << endl;
getline(cin, (b[x].title));
cout << "Enter the author's name:" << endl;
getline(cin, (b[x].author));
cout << "Enter the no. of pages:" << endl;
cin >> b[x].no_of_pages;
cout << "Enter the price of book:" << endl;
cin >> b[x].price;
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
cin.ignore(1000, '\n');
That said I would just read everything using getline, then convert the strings to numbers where needed. That's simpler and cleaner, all you need to know is how to convert a string to an integer, which you can easily research for yourself.
There are two places you should put cin.ignore in your code:
cout << "Enter the no. of books whose details are to be entered:" << endl;
cin >> N;
// First cin.ignore here
cin.ignore(1000, '\n');
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
// Second cin.ignore here
cin.ignore(1000, '\n');
Besides this I see two more problems in your code:
#include <string> not <string.h>
add #include <iostream>
Why cin.ignore is necessary? User is expected to provide new line ('\n') delimited input. When getline is used, it leaves the input stream in such a state that the next attempt to read input from stream will start at next line. This is not true for operator >>. What int x; cin >> x; does here is it reads only the integer not the new line character present right after the integer. Hence, the next attempt to read will continue within the same line. getline will then find no character before new line and hence will fetch an empty string. To avoid this and to effectively start reading from the next line, cin.ignore is necessary.

Using a struct to hold information entered by the user C++

Okay, so I am writing a C++ program to declare a struct data type that holds the following information on an employee (First Name, Last Name, ID, Pay Rate, and Hours). My problem is that the user can only enter in the ID and First Name, then the whole program runs without letting the user enter the rest of the data.
Heres my code:
#include <iostream>
#include <iomanip>
using namespace std;
struct Employee
{
int employeeID;
char firstName;
char lastName;
float payRate;
int hours;
};
int main()
{
int i, j;
cout << "How Many Employees Do You Wish To Enter?:\n\n";
cin >> j;
Employee info;
for (i = 0; i < j; i++)
{
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << setw(5) << "\n Please Enter The Employee ID Number: ";
cin >> info.employeeID;
cout << setw(5) << "\n Please Enter Employees First Name: ";
cin >> info.firstName;
cout << setw(5) << "\n Please Enter Employees Last Name: ";
cin >> info.lastName;
cout << setw(5) << "\n Please Enter Employees Pay Rate: ";
cin >> info.payRate;
cout << setw(5) << "\n Please Enter The Hours The Employee Worked:
";
cin >> info.hours;
}
cout << "\n\n \n";
cout << "ID" << setw(15) << "First Name" << setw(10) << "Last Name" <<
setw(10) << "Pay Rate" << setw(10) << "Hours";
cout << endl;
for (i = 0; i < j; i++)
{
cout << "\n" << info.employeeID << setw(15) << info.firstName << setw(10) << info.lastName << setw(10) << info.payRate << setw(10) << info.hours;
}
cout << "\n\n \n";
system("pause");
return 0;
};
#include <iostream>
#include <iomanip>
#include <string> //Allows you to use strings, which are way more handy for text manipulation
#include <vector> //Allows you to use vector which are meant to be rezied dynamicaly, which is your case
using namespace std;
struct Employee
{
int employeeID;
string firstName; //HERE : use string instead of char (string are array of char)
string lastName; //HERE : use string instead of char
float payRate;
int hours;
};
int main()
{
int j;
cout << "How Many Employees Do You Wish To Enter?:\n\n";
cin >> j;
vector<struct Employee> info; //creation of the vector (dynamic array) to store the employee info the user is going to give you
for (int i = 0; i < j; i++) //declare your looping iterator "i" here, you will avoid many error
{
struct Employee employee_i; // create an employee at each iteration to associate the current info
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << "\n Please Enter The Employee ID Number: ";
cin >> employee_i.employeeID;
cout << "\n Please Enter Employees First Name: ";
cin >> employee_i.firstName;
cout << "\n Please Enter Employees Last Name: ";
cin >> employee_i.lastName;
cout << "\n Please Enter Employees Pay Rate: ";
cin >> employee_i.payRate;
cout << "\n Please Enter The Hours The Employee Worked: ";
cin >> employee_i.hours;
info.push_back(employee_i); //store that employee info into your vector. Push_back() methods expands the vector size by 1 each time, to be able to put your item in it
} // because you employee variable was create IN the loop, he will be destruct here, but not the vector which was created outside
cout << "\n\n \n";
for (int i = 0; i < j; i++) //the loop to get back all the info from the vector
{
cout << "ID :" << info[i].employeeID << " First Name :" << info[i].firstName << " Last Name :" <<
info[i].lastName << " Pay Rate :" << info[i].payRate << " Hours :"<< info[i].hours;
cout << endl;
//notice the info[i], which leads you to the employee you need and the ".hours" which leads to the hours info of that specific employee
}
system("pause");
return 0;
}
First, please read Tips and tricks for using C++ I/O (input/output). It might be helpful to understand C++ I/O.
Here are some comments on your code:
First
Use string instead of char.
struct Employee
{
int employeeID;
string firstName;
string lastName;
float payRate;
int hours;
};
Second
Use array of Employee object to store multiple employees.
Employee info[100];
Third
Use cin carefully depending data types. In your case, it would be something like this:
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << setw(5) << "\n Please Enter The Employee ID Number: ";
cin >> info[i].employeeID;
cin.ignore(); //It is placed to ignore new line character.
cout << setw(5) << "\n Please Enter Employees First Name: ";
getline (cin, info[i].firstName);
cout << setw(5) << "\n Please Enter Employees Last Name: ";
getline (cin, info[i].lastName);
cout << setw(5) << "\n Please Enter Employees Pay Rate: ";
cin >> info[i].payRate;
cout << setw(5) << "\n Please Enter The Hours The Employee Worked: ";
cin >> info[i].hours;
Fourth
std::getline() can run into problems when used before std::cin >> var. So, std::cin.ignore() can be used in this case to solve the problem.
I hope it helps.

Run time error of cin.get() [duplicate]

This question already has answers here:
Using getline(cin, s) after cin [duplicate]
(13 answers)
Closed 5 years ago.
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
void cpp_string();
void cstyle_string();
int main()
{
cpp_string();
cstyle_string();
system("pause");
return 0;
}
void cpp_string()
{
string fName, lName;
char grade;
int age;
cout << "What is your first name?";
getline(cin, fName);
cout << "What is your last name?";
getline(cin, lName);
cout << "What letter grade do you deserve?";
cin >> grade;
cout << "What is your age?";
cin >> age;
cout << "Name: " << fName << ", " << lName << endl;
cout << "Grade: " << grade << endl;
cout << "Age: " << age << endl;
return;
}
void cstyle_string()
{
char fNm[20], lNm[20];
char grade;
int age;
cout << "What is your first name?";
cin.get(fNm, 20).get();
cin.clear();
cout << "What is your last name?";
cin.get(lNm, 20).get();
cout << "What letter grade do you deserve?";
cin >> grade;
cout << "What is your age?";
cin >> age;
cout << "Name: " << fNm << ", " << lNm << endl;
cout << "Grade: " << grade << endl;
cout << "Age: " << age << endl;
return;
}
I'm getting output as
What is your first name?demiurge conon
What is your last name?no
What letter grade do you deserve?a
What is your age?22
Name: demiurge conon, no
Grade: a
Age: 22
What is your first name?What is your last name?What letter grade do you deserve?What is your age?Name: ,
Grade: ╠
Age: -858993460
Press any key to continue . . .
but if I run cstyle_string() in different file then I'm not getting any errors code works perfectly.
I want to know why this is happening?
There are two question.
Redundant \n
the state of cin
The last cin in cpp_string is cin >> age.
It will leave a \n not extracted.
In first of cstyle_string is cin.get(fNm, 20).get();
The delimiting character is not extracted from the input sequence if found, and remains there as the next character to be extracted from the stream
the cin.get(FNm, 20) will parse empty input before \n, and no characters are available in the stream in actually. In this case, the failbit flag will be set and next all cin >> operator will fail.
You can only call cstyle_string and press enter directly, the same thing will happen.

"getline" prompt gets skipped, not working as intended

Here are my codes:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int age1;
int age2;
string name1;
string name2;
cout << "Please enter the name for one people: " << "\n";
getline (cin, name1);
cout << "Please enter the age for this people: " << "\n";
cin >> age1;
cout << "Please enter the name for another people: " << "\n";
getline (cin, name2);
cout << "Please enter the age for this people too: " << "\n";
cin >> age2;
if ( (age1 <= 100 || age2 <= 100) && (age1 < age2) )
{
cout << name1 << " is younger!" << "\n";
}
else if ( (age1 <= 100 || age2 <= 100) && (age1 > age2) )
{
cout << name2 << " is younder!" << "\n";
}
else if ( (age1 <= 100 || age2 <= 100) && (age1 = age2) )
{
cout << name1 << " and " << name2 << " are of the same age!" << "\n";
}
else
{
cout << "You've got some really old people that are well older than 100!";
}
}
The first getline and cin works fine. I am able to be prompted to input.
However, the second getline and cin are prompted at once, thus I can only input for cin. (The second getline is skipped!)
If I use four cins, the program will work properly.
cin >> age1; does not read the newline character following the number. The newline remains in the input buffer, then prematurely stops the second getline.
So, your program already works as long as you enter the first age and the second name on the same line.
One solution would be to skip whitespace after the numbers:
cin >> age1 >> ws;
Live demo.
first: cin>>age; It takes the number and stores into age but at the same
time it leaves the newline character in the buffer itself. so when there is prompt for next name cin finds that left over newline character in the buffer and takes it as the input. that it why it escapes the name2 prompt.
cout << "Please enter the name for one people: " << "\n";
cin>>name1;
cout << "Please enter the age for this people: " << "\n";
cin >> age1;<<--**this left the new line character in input buffer**
cin.get();<<-- **get that newline charachter out of there first**
cout << "Please enter the name for another people: " << "\n";
getline (cin, name2);
cout << "Please enter the age for this people too: " << "\n";
cin >> age2;
now i give name1-> shishir age1->28
name2->ccr age-> 22 it prints ccr is younder!<-- the spelling is wrong too :D
for more info on getline and get() read c++ primer plus listing 4.3, 4.4, 4.5
Happy coding
You need a ; after getline (cin, name);
hope this helps
I would suggest using cin.ignore(100,'\n'). It ignores the amount of characters you specify when you call it(100 in the example above), up to the char you specify as a breakpoint. For example:
cout << "Please enter the name for one people: " << "\n";
getline (cin, name1);
cout << "Please enter the age for this people: " << "\n";
cin >> age1;
cin.ignore(100, '\n');
cout << "Please enter the name for another people: " << "\n";
getline (cin, name2);
cout << "Please enter the age for this people too: " << "\n";
cin >> age2;
cin.ignore(100, '\n');

C++ simple code issue about cout and cin

I have the following code. Everything works fine but quite different. I expect the first three cout << come one after the another, so when the first message is shown in the console, the user enters the value, and then the next cout << shows another message and the user enters the name of the book, and then the third cout << shows the last message and the user enters the year. But it shows the first message for, I enter the value, and then it shows the next two messages together. Why?
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
string AuthorName;
string AuthorBook;
string YearPublished;
cout << "Please Enter the Author Name" << endl;
cin >> AuthorName;
cout << "Please enter the Author Book" << endl;
cin >> AuthorBook;
cout << "Please enter the year when the book was published" << endl;
cin >> YearPublished;
cout << setw(15) << "Author Name";
cout << setw(15) << "Prominent Work";
cout << setw(15) << "Year Published";
cout << endl << endl;
cout << setw(15) << AuthorName;
cout << setw(15) << AuthorBook;
cout << setw(15) << YearPublished;
cout << endl << endl;
return 0;
}
You need to use getline() since C++ stops reading your input at the first space in strings using cin.