Using cin to get user input.

Pages: 12
Too many questions keep popping up with the same problem. How do I get user input from cin using >> into X type. Using the >> operator opens you up to alot of problems. Just try entering some invalid data and see how it handles it.

Cin is notorious at causing input issues because it doesn't remove the newline character from the stream or do type-checking. So anyone using cin >> var; and following it up with another cin >> stringtype; or getline(); will receive empty inputs. It's best practice to NOT MIX the different types of input methods from cin.

I know it's going to be easier to use cin >> integer; than the code below. However, the code below is type-safe and if you enter something that isn't an integer it will handle it. The above code will simply go into an infinite loop and cause undefined behaviour in your application.

Another dis-advantage of using cin >> stringvar; is that cin will do no checks for length, and it will break on a space. So you enter something that is more than 1 word, only the first word is going to be loaded. Leaving the space, and following word still in the input stream.

A more elegant solution, and much easier to use is the getline(); function. The example below shows you how to load information, and convert it between types.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main() {

 string input = "";

 // How to get a string/sentence with spaces
 cout << "Please enter a valid sentence (with spaces):\n>";
 getline(cin, input);
 cout << "You entered: " << input << endl << endl;

 // How to get a number.
 int myNumber = 0;

 while (true) {
   cout << "Please enter a valid number: ";
   getline(cin, input);

   // This code converts from string to number safely.
   stringstream myStream(input);
   if (myStream >> myNumber)
     break;
   cout << "Invalid number, please try again" << endl;
 }
 cout << "You entered: " << myNumber << endl << endl;

 // How to get a single char.
 char myChar  = {0};

 while (true) {
   cout << "Please enter 1 char: ";
   getline(cin, input);

   if (input.length() == 1) {
     myChar = input[0];
     break;
   }

   cout << "Invalid character, please try again" << endl;
 }
 cout << "You entered: " << myChar << endl << endl;

 cout << "All done. And without using the >> operator" << endl;

 return 0;
}


Last edited on
Well said. In fact, I have an idea...this post should be stickied (no that wasn't my idea).
is there a way for a user input information without it being displayed to the monitor, such as entering a passord?
Without using OS specific stuff (or maybe ncurses, but I don't think it let you do that), no. Otherwise, go look it up for your OS of choice.
Last edited on
You spelled "elegant" wrong. ;)

You spelled "elegant" wrong. ;)


Of course he spelled it wrong. Did you forget what kind of website this is? Programmers can't spell.
Indeed I did. Unfortunately, New Zealand has a terrible accent and it makes it difficult to spell phonetically. "Elegant" is said as "elegent" so when touch-typing I often revert to a phonetic style of spelling. That is also why you will notice I spell worlds like Organisaton with an S, and not a Z. UK spelling.

But as Buff mentioned. Most programmers are notoriously terrible at spelling.
> Most programmers are notoriously terrible at spelling.
Oh, yeah! Vindication! I feel a lot better about being such a poor speller now! (I'm serious, too.)

On *nix, there is often a convenient little function called getpass()
http://linux.die.net/man/3/getpass

On Windows, you will usually want to mess with the Credentials API. There is an excellent article on this subject here: http://msdn.microsoft.com/en-us/magazine/cc163883.aspx

For a simple console application though... you can just turn off echo with SetConsoleMode().

Hope this helps.
Really nice way to validate user input .. Thanks !
I have question regarding to this:
what is the difference between:
cin.getline(buf,100); // where char buf[100]
and using getline(cin,input); // Above code segment
Let me know asap

cin.getline is for C strings (character arrays)
getline is for C++ strings
@cppg2009: The difference is that using a char array is a C style of handling the information. Your also limited to a maximum of 100 characters being loaded into your array. The string method allows an un-restricted number of characters to be loaded.

You also avoid stupid issues like non null-terminated character arrays causing problems when being used.
i'm having a problem when i run the program from the sample
#include <iostream>
#include <string>
using namespace std;

int main ()
{
string mystr;
cout << "What's your name? ";
getline (cin, mystr);
cout << "Hello " << mystr << ".\n";
cout << "What is your favorite team? ";
getline (cin, mystr);
cout << "I like " << mystr << " too!\n";
return 0;
}
i entered a full name(under variable mystr), then it was displayed like what it has to be in the line
cout<<"hello"<<mystr<<".\n"; then i entered my favorite team but the 2nd value of mystr didn't displayed anymore, it only displayed "i like" then blank , i'd like to know why please reply thanks.
I vote for moving this to the Beginners forum and stickying it there.
@awing: That works fine for me. But if your having problems, before the 2nd getline(); try putting cin.clear();
@ zaita: ok i'll try it! thanks a lot
Last edited on
I think it would be much easier to get input from user using a much simplier code like

1
2
3
4
5
6
void main (void){
int input = 0;
cout << "Enter a number here: ";
cin >> input;
cout << "You entered the number " << input << ".\n";
}


for numbers and

1
2
3
4
5
6
7
8
void main (void){
char input[100]; /*you can use any other number of elements in the array. 
Each element is one character of your string, 
always put one more for the null at the end of the string.*/
cout << "Enter some text here: ";
cin >> input;
cout << "You entered:\n " << input << "\n";
}


for a string.
Last edited on
@kikolani
no, that gives a lot problems. If you use cin>>int and the user enters "hallo" you're program will most likely crash or at least it won't do what it should do. And that's only one of the problems when using cin>>. In simple programs for school-assigments etc. you may use cin>> but in 'real' programs always use the solutions Zaita presented here when possible.
I came to Zaita's conclusion some time ago too.
IMO the cin stream is just to prone to user input error
and in a situation like this cin >> a >> b >> c, once one
part fail everything following tend to fail.

I started to wite some functions but as template functions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <typename X> 
void readCIN(X& var)
{
    string str;
    stringstream sstream;
    getline(cin,str);
    sstream << str.c_str(); //could be written as sstream(str.c_str())
    sstream >> var;
}

template <typename X>
void readStream(istream& stream, X& var)
{
    string str;
    stringstream sstream;
    getline(stream,str);
    sstream << str.c_str(); //could be written as sstream(str.c_str())
    sstream >> var;

}


Still Work in progress.
I know you can't chain inputs this way, but I think it's safer.
Pages: 12