Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Program skips cin.getline()

I have made this program, It get the users adress, name and work. Then It puts it all into one string and outputs that string. (I know there are better ways to do this)

char str[600];
char adrs[200];
char name[10];
char wrk[200];
cout<<"Enter your name and press ENTER: ";
cin.getline(name,10);
cout<<"\nEnter your adress and press ENTER:";
cin.getline(adrs,200);
cout<<"\nEnter your workplace and press ENTER:";
cin.getline(wrk,200);
strcpy(str,"My name is ");
strcat(str,name);
strcat(str,"\nand i live at ");
strcat(str,adrs);
strcat(str, "\nI also work at ");
strcat(str, wrk); strcat(str, "\n\n");
cout<<str<<endl;

Here when I write a name that exceeds 10 chars The program does take the first 9 chars the user entered as I expected but after that It skips all the next cin.getline() That are in the program and goes to output str and ends the program.

Why does this happen and how to fix it?

like image 290
Mohamed Ahmed Nabil Avatar asked Aug 06 '12 20:08

Mohamed Ahmed Nabil


2 Answers

Every time you use cin, it stores every character entered in memory until it encounters a newline character. This block of memory is called the input buffer. Your first call to cin.getline() requests a string with 10 characters, including the terminating NULL character. However, cin happily reads as many characters as the user types until he hits the Enter key. If the user types more than 9 characters, then cin stores the remaining characters in the input buffer and will use them during later input operations. For example, if the user types 15 characters, your call to cin.getline() store the first nine in your c-string array. Calling cin.getline() again will then continue reading the remainder of the input that was already entered.

To fix this problem, you should use cin.ignore() to skip past this newline character. I strongly suggest that you familiarize yourself with online references to the C++ libraries. Two of my favorites are http://www.cplusplus.com and http://www.cppreference.com.

Edit: In order for my answer to be complete, I also need to add that cin.getline() will set the fail bit if there are more characters in the input buffer than requested. Before using cin for any additional input operations, you must call cin.clear() to clear the fail bit.

like image 136
Code-Apprentice Avatar answered Sep 17 '22 16:09

Code-Apprentice


When a too-long string is read, ios_base::failbit is set for the stream and all subsequent operations against the stream will fail. You need to reset the failure with ios::clear:

if (cin.fail())
    cin.clear();

After the error is cleared you may want to ignore the rest of the line with istream::ignore.

Edit: It took a helpful hint for me to figure out how to use ignore properly. Here's the total solution.

cout<<"Enter your name and press ENTER: ";
cin.getline(name,10);
if (cin.fail())
{
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

I would suggest putting all that code into a function so that you can call it after every getline.

like image 22
Mark Ransom Avatar answered Sep 18 '22 16:09

Mark Ransom