C++ is skipping the first cin.getline method [duplicate] - c++

This question already has answers here:
C++ Getline after Cin
(3 answers)
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
I am developing a program where I am calling cin.getline() to get values from the user. My program is logically correct and program runs but, it somehow skips the first cin.getline() method and calls the second one and onwards.
Here's my code:
public:
Library()
{
myFile.open("testFile.txt", ios::app);
myFile2.open("testFile.txt", ios::in);
cout<<"Constructor calling"<<endl;
}
void addBookData()
{
cout<<"Enter a Book Name: "; // this gets printed
cin.getline(bookName, 50); // skips this, doesn't take input from user
cout<<"Enter the Author's Name: "; // this gets printed
cin.getline(authorName, 50); // takes value from the user here
cout<<"Enter the Genre: ";
cin.getline(genre, 30);
cout<<"Enter number of pages: ";
cin >> noOfPages;
cout<<"Enter rating: ";
cin >> rating;
cout<<"Enter language: "; // again this gets printed
cin.getline(language, 20); // this gets skipped as well
cout<<"Issued to (Username): ";
cin.getline(issuedTo, 30); // takes value from here
cout<<"Issued date: ";
cin.getline(issuedDate, 30);
myFile <<"Book Name: " << bookName << endl << "Author's Name: " << authorName << endl <<
"Genre: " << genre << endl << "Number of pages: " << noOfPages << endl << "Rating: " <<
rating << endl << "Language: " << language << endl << "Issued to (Username): " << issuedTo
<< endl << "Issued date: " << issuedDate << endl;
}
Can anybody explain to me why is this happening? What am I doing wrong? Any help would be appreciated. Thanks.

Related

How can I stop cin from skippping a line? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
cin and getline skipping input [duplicate]
(4 answers)
Closed last year.
I was trying to make a program where the user is asked to give an input and it gives output with answered questions. Everything looks alright except that cin skipped my last question about school.
This is the original code:
//this program fills my data in profile
#include <iostream>
#include <string>
using namespace std;
int main () {
int age, exp_years;
char desired_grade;
string school_name, name;
const int year_grad = 4;
bool is_student;
cout << "You will need to enter your data for portfolio card" << endl;
cout << "Enter your last name" << endl;
cin >> name;
cout << "Enter your age" << endl;
cin >> age;
cout << "Enter your years of work experience" << "\n";
cin >> exp_years;
cout << "Is it true or false that you are a student (put 'true' or 'false')" << endl;
cin >> is_student;
cout << "Great! What school are you in (if you are not a student put desirable school)?" << endl;
cin >> school_name;
/* trying to make a function below */
cout << "Awesome, here is your info" << endl << "Your last name is "<< name << endl <<"You are "<<age << " years old." << endl << exp_years << " years of work experience" << endl;
if ( is_student == 1)
{
cout << school_name << " is lucky to have you!\n";
return 0;
} else {
cout << "Btw I am sure that " << school_name << " would be happy to have you as their student anytime\n";
return 0;
}
return 0;
}
I read some article and they said that getline() can help, so I tried to substitute with:
cout << "Is it true or false that you are a student (put 'true' or 'false')" << endl;
getline(cin, is_student);
cout << "Great! What school are you in (if you are not a student put desirable school)?" << endl;
getline(cin, school_name);
Hovewer, it gives me an error:
error: no matching function for call to 'getline'
What am I missing?
It seems the problem is related to entering a boolean value.
Here is shown how to enter boolean values
#include <iostream>
#include <iomanip>
int main()
{
bool is_student;
std::cin >> is_student; // accepts 1 as true or 0 as false
std::cout << is_student << '\n';
std::cin >> std::boolalpha >> is_student; // accepts strings false or true
std::cout << is_student << '\n';
}

New to structures, I'm confused about how to return values out of a void function and put it into another function

my C++ class just started learning about developing structures. I'm stuck on a homework problem where I'm asked to write a program that uses a structure named movie_data and two movie_data variables to display information about a movie. I'm able to develop the movie_data structure correctly along with the two variable to outsoruce to a function named get_movie_info. However, because I set it as a void function, I'm unable to return anything produced by the get_movie_function to send to my movie_display function. I tried rewriting my functions to be of the movie_data structure data type, but that seemed to make things worse. The first function produces all the information correctly, but the second function doesn't output anything. Thank you for your time.
#include <iostream>
#include <iomanip>
using namespace std;
struct movie_data
{
string title;
string director;
int year_released;
int running_time;
};
//Function Prototype
void get_movie_info(movie_data movie1, movie_data movie2);
void movie_display(movie_data movie1, movie_data movie2);
int main()
{
movie_data movie1;
movie_data movie2;
get_movie_info(movie1, movie2);
movie_display(movie1, movie2);
return 0;
}
void get_movie_info(movie_data movie1, movie_data movie2)
{
//Get movie_data's title
cout << "Enter the title for the first movie: ";
//cin.ignore();
getline(cin, movie1.title);
cout << movie1.title << endl;
//Get movie_data's director
cout << "Enter the director's name for " << movie1.title << ": ";
//cin.ignore();
getline(cin, movie1.director);
cout << movie1.director << endl;
//Get movie_data's release year
cout << "Enter the release year for " << movie1.title << ": ";
cin >> movie1.year_released;
cout << movie1.year_released << endl;
//Get movie_data's running time
cout << "Enter the runtime of " << movie1.title << " in minutes: ";
cin >> movie1.running_time;
cout << movie1.running_time << " minutes" << endl;
//Get movie_data's title
cout << "Enter the title for the second movie: ";
cin.ignore();
getline(cin, movie2.title);
cout << movie2.title << endl;
//Get movie_data's director
cout << "Enter the director's name for " << movie2.title << ": ";
//cin.ignore();
getline(cin, movie2.director);
cout << movie2.director << endl;
//Get movie_data's release year
cout << "Enter the release year for " << movie2.title << ": ";
cin >> movie2.year_released;
cout << movie2.year_released << endl;
//Get movie_data's running time
cout << "Enter the runtime of " << movie2.title << " in minutes: ";
cin >> movie2.running_time;
cout << movie2.running_time << " minutes" << endl;
}
void movie_display(movie_data movie1, movie_data movie2)
{
//Display movie1 information
cout << "\nBelow is the data of the first movie:\n";
cout << "Movie Title: " << movie1.title << endl;
cout << "Director's Name: " << movie1.director << endl;
cout << "Release Year: " << movie1.year_released << endl;
cout << "Movie Runtime in minutes: " << movie1.running_time << endl;
//Display the movie information
cout << "\nBelow is the data of the second movie:\n";
cout << "Movie Title: " << movie2.title << endl;
cout << "Director's Name: " << movie2.director << endl;
cout << "Release Year: " << movie2.year_released << endl;
cout << "Movie Runtime in minutes: " << movie2.running_time << endl;
}
While #Kai's answer of using refrences would work and correctly would answer your original question, I suggest doing something else.
First, use a function to read in only one move_data and make it return that:
movie_data get_movie_info();
A possible implementation (using your code) could be like this:
movie_data get_movie_info(){
movie_data movie;
cout << "Enter the title for the first movie: ";
getline(cin, movie.title);
cout << "Enter the director's name for " << movie.title << ": ";
getline(cin, movie.director);
cout << "Enter the release year for " << movie.title << ": ";
cin >> movie.year_released;
cout << "Enter the runtime of " << movie.title << " in minutes: ";
cin >> movie.running_time;
return movie;
}
Now you can call it twice to read your info and it will return the movie data as the correct structure.
movie_data movie1 = get_movie_data();
If you need to have structs that can be edited, references are a good choice. For returning multiple values, there are better choices: An array of a suitable size (std::array), a Pair for two, or a vector of Objects.
It's better to avoid having output parameters (as a rule of thumb, break it if you need to and know why) as they are hard to grasp from the signature and hard to keep track of.
Notice, that you do everything twice. The point of using functions, is to not do everything twice, so you should write one function to do one thing and just call it with different parameters. For example in get_movie_info. A better design would be to create a function that creates exactly one movie_data and returns it:
movie_data get_movie_info()
{
movie_data result = {}; // That's the variable were we store the data
//Get movie_data's title ...
//Get movie_data's director ...
//Get movie_data's release year ...
//Get movie_data's running time ...
return result; // return the created movie data
}
The same goes for movie_display. Don't create a function that does exactly the same thing for two parameters, but create a function that does it one time and call it twice:
void movie_display(movie_data movie)
{
cout << "Movie Title: " << movie.title << endl;
//And so on ...
}
Then you combine both in the main like this:
int main()
{
movie_data movie1 = get_movie_info();
movie_data movie2 = get_movie_info();
std::cout << "data of the first movie:\n";
movie_display(movie1);
std::cout << "data of the second movie:\n";
movie_display(movie2);
return 0;
}
Update your function signatures to take references instead of values.
https://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/
void get_movie_info(movie_data& movie1, movie_data& movie2)
void movie_display(const movie_data& movie1, const movie_data& movie2)

Just started coding C++ [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
What seems to be the problem in my code?
When I hit Enter after entering my age, the prompt already finishes without asking for my address. I know I can use getline() for the age, but what if the user enters a non-integer answer?
Sorry, I just started coding yesterday and I want to learn the basics.
#include <iostream>
using namespace std;
int main()
{
int age;
string name, address;
cout << "Please enter the name of the user:" << endl;
getline(cin, name);
cout << "Please enter age of the user:" << endl;
cin >> age;
cout << "Please enter the address of the user:" << endl;
getline(cin, address);
cout << "Your name is " << name << " and you are " << age
<< " years old " << " who lives in " << address << endl;
cout << "Thank you for using my program!";
return 0;
}
Just add 'cin.ignore()' after 'cin>>age' like this:
cout << "Please enter age of the user:" << endl;
cin >> age;
cin.ignore();
cout << "Please enter the address of the user:" << endl;
getline(cin, address);
When getline() reads input, then a newline character is left in input stream, due to which it dosen't reads the string(address) in your program.
And if a user enters a 'float' or 'double' etc. instead of 'int' in age then it will simply extract out integer from it ,
for example:
if user enters 39.29 or 39.00005 or 39.00 or then age=39
To know more about getline check the following link:

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.

Code not allowing user input in strings after first string

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();