3

I looked at some other questions and I'm too newbish at C++ to know if they applied to my question here..

Basically when show the output of "name", if I type in my full name it only shows the second word. Before, it wasn't even taking anything at all, it just skipped it. I'm confused at the moment for something so seemingly simple. THanks.

#include <iostream>
#include <string>
using namespace std;

int main()
{
double money;
string name;
int age;

// Prompt for age and receive
cout<<"How old are you? ";
cin >> age;

// Prompt for money and receive
cout<<"How much money do you have?";
cin >> money >> endl;

// Prompt for name and receive
cout<<"What's your name?\n\n"<< endl;
getline(cin, name);

// Display all information to user
cout<<"Hello, "<< name <<".";
cout << "You are " << age << " years old";
cout<< " and have $" << money << ".\n";

system("PAUSE");
return 0;
}
2
  • 2
    Don't mix getline and >> unless you really understand how to handle newlines. In your case, just always use getline.
    – Kerrek SB
    Commented Aug 29, 2013 at 22:22
  • cin >> money >> endl; Does this compile ? I tried here and got tons of errors...
    – zentrunix
    Commented Aug 29, 2013 at 23:19

2 Answers 2

4

The problem is that formatted input using >> reads a value and stops once the value is completely parsed. For example, a number is completed once something not matching the format appears. That is, the reading would stop right in front of a space or a newline (and quite a few other characters). Normally these extra characters don't cause an problems because formatted input starts off with skipping leading whitespace (space, tab, newline, etc.) before attempting to read the actual value.

However, unformatted input, e.g., getline() starts to read its value immediately and stops once it encounters a newline (or the character specified as the newline character if the three argument version is used). That is, getline() would immediately stop after reading the newline character if that is left in the stream.

The easiest way to get rid of the newline character (and any other leading whitespace) is to use std::ws, e.g.:

if (std::getline(std::cin >> std::ws, name)) {
    ...
}

... and, BTW, whenever you attempt to read something you should always check after reading that the attempt to read the value was successful!

Another approach is not to use std::getline() at all and instead just use the formatted input for the name, too. However, that assumes that there isn't any space in the name.

1
  • Note that the suggested fix will mean that a blank line is skipped over in the whitespace search ; it might be intended for a blank line to be read as an empty string
    – M.M
    Commented Aug 27, 2018 at 5:53
0

That's because the newline from the "How much money do you have?" reply is still in the input buffer. In general it is not a good idea to mix item input and line-based input (whether using C and scanf/fgets or C++ >> and getline), because you get these sort of problems.

You can fix this particular situation by using char dummy = cin.get(); before somewhere before getline, however, you have to do that every time you switch from "item input" to "line input", and if you later change the order, you have to remember to move the cin.get() along.

A better solution is to ALWAYS use line-based input, and then use stringstream to get the data out of the string, so something like this:

string ageString;
getline(cin, ageString);
stringstream ageSs(ageString);
if (!ageSs >> age)
{
    cout << "Bad input" << endl;
    exit(1);    // You may of course want to repeat rather than exit... 
}

That way, you are reading a whole line, no matter what the input is.

Not the answer you're looking for? Browse other questions tagged or ask your own question.