-2

I have a database class that is an array that will hold a number of objects. The function will take a couple of inputs from the user which include both strings and ints

For example:

std::cout << "Enter first name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, first_name);
std::cout << "Enter last name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, last_name);
std::cout << "Enter age: ";
std::cin >> age;

When I run the code, after I hit enter after entering the last name, it just starts a new line and I have to enter another input before it asks for the age input.

I heard it was bad to mix getline and cin, and that it's better to use one or the other. What can I do to make this work and what would be good practice moving forward?

Edit: I added in the ignores when I initially searched for solutions because without them, the code wouldn't bother waiting for user input. The output would be "Enter first name: Enter last name: "

Edit2: RESOLVED. Problem was I had used "cin >>" earlier in my code for user to input an int variable and needed the first cin.ignore statement, but not the other. Did not include that part of the code because I didn't know that was affecting it. Still new to all this so thanks everyone for their help!

ptu27
  • 13
  • 4

3 Answers3

2

Your std::cin::ignore calls are not helping you. They are only needed after an input that does not extract the end-of-line character (>>).

std::string first_name;
std::string last_name;
int age;

std::cout << "Enter first name: ";
std::getline(std::cin, first_name); // end of line is removed

std::cout << "Enter last name: ";
std::getline(std::cin, last_name); // end of line is removed

std::cout << "Enter age: ";
std::cin >> age; // doesn't remove end of line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // this does
// input can proceed as normal

You only need the std::cin::ignore call after std::cin >> age; because that doesn't remove the end of line character whereas the std::getline calls do.

Galik
  • 47,303
  • 4
  • 80
  • 117
  • When I remove the ignore lines, the output in console goes straight from "Enter first name: " to "Enter last name: ", so output reads "Enter first name: Enter last name: " before allowing user input – ptu27 May 21 '16 at 16:50
  • @ptu27 Do you have other code performing input operation before the one you showed? – Biruk Abebe May 21 '16 at 16:52
  • @bkVnet Yea. I have a user input for an int. Program outputs a list of options and user will input an int to select which option via std::cin – ptu27 May 21 '16 at 17:02
  • @put27 That is why, if you used the extraction `operator>>`,like `cin>>x`, before using `getline` then you need to call `ignore`. So leave the first `ignore` and remove the other. – Biruk Abebe May 21 '16 at 17:04
  • @bkVnet Thank you!! Just did that and it fixed it. Also fixed the same problem I was having elsewhere in the code. Only started teaching myself 2 weeks ago so everything is still new to me. – ptu27 May 21 '16 at 17:09
1

I recommend removing the ignore function calls:

std::string name;
std::cout << "Enter name: ";
std::getline(cin, name);
unsigned int age;
std::cout << "Enter age: ";
std::cin >> age;
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • I didn't have ignore lines initially, but I kept getting the output: "Enter first name: Enter last name: ". I looked around for some solutions and that's what I came across. – ptu27 May 21 '16 at 16:52
1

According to the documentation of std::basic_istream::ignore(), this function behaves as an Unformatted Input Function which mean it is going to block and wait for user input if there is nothing to skip in the buffer.

In your case both of your ignore statments are not neccessary since std::getline() will not leave the new line character in the buffer. So what is actually happening is:

std::cout << "Enter first name: ";
/*your first input is skipped by the next ignore line because its going to block until
input is provided since there is nothing to skip in the buffer*/
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
/* the next getline waits for input, reads a line from the buffer and also removes the 
new line character from the buffer*/
std::getline(std::cin, first_name);

std::cout << "Enter last name: ";
/*your second input is skipped by the next ignore line because its going to block until
input is provided since there is nothing to skip in the buffer*/
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
/* the next getline waits for input and this is why it seems you need to provide 
another input before it ask you to enter the age*/
std::getline(std::cin, last_name);

You need to remove the ignore statments to make this work. You may also want to read When and why do I need to use cin.ignore() in C++

Community
  • 1
  • 1
Biruk Abebe
  • 2,235
  • 1
  • 13
  • 24