Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

cin.getline problem 2

Status
Not open for further replies.

rafa26

Technical User
Feb 23, 2005
3
0
0
PR
Hi there

Ihave this program that i enter certain ammount of movie names their directors and year made in three different arrays using cin.getline(stringname[],lengthsize,'\n').
The part of the code is as follows:

for(i=0;i<3;i++)
{
cout<<"Enter Movie: "<<i+1<<endl;
cin.getline(movie,50,'\n');

cout<<"Enter Director: "<<i+1<<endl;
cin.getline(director,50,'\n');
cout<<"Enter Year: "<<i+1<<endl;
cin.getline(year,50,'\n');
}
if(i==10)
cout<<"The list is full!"<<endl;

break;

The problem is that when I run the program it will go to "Enter Movie" (no cursor to enter the movie name)and goes right away to "Enter Director" when i = 0 only???
 
Did you do something like this just before entering the loop

Code:
cin >> somenumber;

Basically, you have unused input (usually just a newline) left on the input stream. Unfortunately for you, this is just what getline needs, and so it appears to do nothing.

The solution:
1. Always use getline() for reading all input, then convert it from memory.
2. Before you enter the loop, do
Code:
cin.ignore();
This should throw away excess input upto the next newline.

--
 
Hi there Salem:

As you said cin.ignore() did the job. But also I have heard that this problem is a bug of this microsoft compiler I have. Thanks for your help again.

Rafa
 
It's certainly not a bug in the compiler, despite its being Microsoft's. If it were a bug in anything, it'd be a bug in the C++ iostreams library.

However, it's not a bug at all. That's the expected behavior of [tt]getline[/tt]. Reread Salem's post; it explains what's going on, which is what's supposed to go on.


To explain it using some "graphics" and a hypothetical program fragment:

Pretend you start off with a blank input buffer:

Input Buffer
Code:

Your code does:
Code:
cout << "Gimme an integer: ";

You user obeys and types "53", causing your program's input buffer to look like:

Input Buffer
Code:

Still blank? Yup. Your terminal doesn't deliver anything to your program until the user presses the ENTER key. Assuming they've used a computer before, they probably will, leaving you with:

Input Buffer
Code:
53\n

Note that there's a newline character in your input buffer, which was placed there when the user pressed ENTER.

Now, say the next line of your program reads:
Code:
cin >> num;

Now that there's something in the input buffer, [tt]cin[/tt] can do its job and read some digits from the input buffer, the use them to set [tt]num[/tt] to an appropriate value.

After it pulls the digits out, you're left with:

Input Buffer
Code:
\n
and [tt]num[/tt] equal to 53.

It didn't do anything with the newline. It's not a digit; it can't be part of this integer [tt]cin[/tt] is trying to read, so [tt]cin[/tt] leaves it in the buffer.

Then, your program does:
Code:
cout << "What's your name? ";

Your user eloquently replies by typing "bob" and pressing ENTER.

Input Buffer
Code:
\nbob\n

Check out that newline that's still there at the beginning. You never got rid of it, so it stays there.

If the next line of your program reads:
Code:
cin.getline(name, 666);
then you've told it to store the next line in the input buffer into [tt]name[/tt].

So it will. It'll read the next line in the input buffer. That means it'll read up to the next newline character. That means it'll read up to the first character in the input stream. That's because the first character in the input stream is a newline. That's because you never cleared that newline out.

Your input buffer will look like:

Input Buffer
Code:
bob\n
and your [tt]name[/tt] will be the blank line that newline read.

Note that getline did remove the newline from the buffer. That's what it's supposed to do. Note also that it didn't put that newline in [tt]name[/tt]. That's also correct behavior.

So instead of using [tt]getline[/tt] right away, you use [tt]ignore[/tt]:
Code:
cin.ignore(666, '\n');
which tells it to throw out everything up to the newline that got left in there.

That gives you:

Input Buffer
Code:
bob\n

When you use [tt]getline[/tt] at this point (after using [tt]ignore[/tt]), there's no newline left at the beginning, so the first newline it hits is the one after "bob" in the buffer.

So [tt]getline[/tt] grabs "bob\n" out of the buffer, leaving you with:

Input Buffer
Code:
and the string "bob" (without the newline) in the [tt]name[/tt] variable.

Just like before, [tt]getline[/tt] removed the newline from the buffer, and left it out of [tt]name[/tt]. Again, that's what [tt]getline[/tt] is supposed to do.

I've actually seen some libraries that get this wrong and leave the newline in the input buffer. That's a bug, but it's in the library, not the compiler.

If your library exhibits that bug, you may have to use [tt]ignore[/tt] after calls to [tt]getline[/tt]. That's only if your library is broken, though.
 
Hi there:

Appreciate both for help.

Is essential to know whats happening inside the computer and to have a good idea of the sequence of place/events to better visualize and understand the proccess.

Rafa
 
Just passing through, chipper, and found the most informative look at getline() that I've EVER seen. A star for the effort there!

Ben

There's no place like 127.0.0.1.
 
Hey everyone,
I dunno if you fixed your program already, but I thought I would add something. When you use getline, you need to flush you in stream. That's what ignore does more or less. What I found you need to do is this:
Code:
cin.clear();
cin.ignore( *what you need to ingore* ); //remember that your buffer size is 1024
cin.clear();
Note that the 2nd clear is needed cause theres a bug in the library and there's ways to crash your program :D

If you're in C, you need the fflush() function, which I guess you could use too.

Hope this helps somewhat.


Jay
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top