enter input variable by SPACE?

Hello all,

I just beginning to learn C++ as my first programming language.
Obviously, I played around with a standard I/O program for starters.

Now I stumbled upon something that I do not find an explanation for: I can read in two string variables from standard input separated by SPACE. I previously thought that each and every input must be confirmed by RETURN (by default).

However, after compiling the below code, I can enter "John[SPACE]Freeman[Return]", which ends up stored in the two variables firstName and surName respectively.
I expected the space to be treated as a character, thus yielding "John Freeman" as variable firstName, leaving surName empty.

Can anyone explain this behaviour to me?

Compiler used: g++ 4.1.2 on Debian etch

Best Regards
Markus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

int main ()

{

	string firstName, surName;

	cout << "Please enter your name: ";

	cin >> firstName >> surName;

	cout << "\nHello " << firstName << " " << surName << "!\n";
	cout << "first name:\t" << firstName << endl; //verify that the names are stored in seperate variables.
	cout << "surname:\t" << surName << endl;

	return 0;

}
That's where new C++ programmers get into trouble: the mental model doesn't match the language model.

Your mental model is correct in the sense that whenever a user is asked to input information he (the user!) expects that he is to press ENTER at the end of every input.

However, the >> operator is whitespace-delimited, not line-delimited. This leads to unexpected failures. For example, Ms. Zappa could answer the question with
Moon Unit Zappa
whereafter 'firstName' would be "Moon" and 'surName' would be "Unit" and "<SPACE>Zappa<ENTER>" would be, as yet, unread. This is, of course, incorrect.

This is not an error in the design of the STL, but rather an error in using it properly. Remember, the >> operator is used to separate information out of a stream. It is not meant to be used for direct user input.

To be correct, we must first fix our program to match the user's mental model:
1
2
3
4
5
6
string firstName, surName;
cout << "Please enter your first name(s): ";
getline( cin, firstName );

cout << "Please enter your last name(s): ";
getline( cin, surName );

In this case, we are getting input by line, rather than by whitespace. Make sense?

So, what about numbers?

I prefer to read everything in as a string, then convert it to a number (or whatever the appropriate object is) if possible:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
string s;
unsigned age;
cout << "Please enter your age: ";
getline( cin, s );
{
  // Try to convert whatever the user typed into an unsigned integer.
  streamstring ss( s );
  ss >> age;
  if (!ss)
  {
    cout << "Alas, \"" << s << "\" is not a valid number.\n";
    return 1;
  }
}
// At this point, I know that 'age' is correctly entered.
if (age < 4) cout << "Precocious scamp, ain't ya?\n";
else if (age > 120) cout << "Yeah, right...\n";
else if ...


The other way (and I'm almost out of time here) is to simply get and discard that ENTER key (and any other garbage in front of it) after reading what you want:
1
2
3
4
unsigned age;
cout << "How old are you? ";
cin >> age;
cin.ignore( numeric_limits<streamsize>::max(), '\n' );


Hope this helps.
Last edited on
Use cin.get(changer, number of charters to fit, ending charter); instead of just cin.

like the following:
cin.get(name, 49); // It's 50, but remember NULL charter. No ending charter set, default is enter.

EDIT: Sorry, I was posting same time and didn't see that post.
Last edited on
Topic archived. No new replies allowed.