i have also similar problem with getline :

int Books::InsertBook()
{
	
	string authorName;
    cout << "id_code :" << endl;
    cin >> bookrec.id_code;
	cout << "info_title :" << endl;
	cin >> bookrec.info_title;
	cout << "author :" << endl;
    getline(cin,authorName);
    int authorID = train_Author::s_add_author(authorName);
	if(authorID==0)
	{
		cout<< "Operation cancelled!" << endl;
		return 4;
	}
	bookrec.author = authorID;
	cout << "publisher :" << endl;
	cin >> bookrec.publisher;
	cout << "pubdate :" << endl;
	cin >> bookrec.pub_date;
	cout << "infotype :" << endl;
	cin >> bookrec.info_type;
	
	d_fillnew(INFO, &bookrec);
    cout << "successful" << endl;
	return 5;
}

it skips getline.

Recommended Answers

All 6 Replies

There's a sticky How do I flush the input stream? that explains your problem and provides several solutions.

Thanks for searching before posting...not! :icon_rolleyes:

cin >> bookrec.info_title;
getline(cin, authorName);

Narue's answer covers it all, but it isn't immediately obvious (at least to me) that it does so. Unfortunately I don't know a straightforward answer, so I'll offer another "explanation" instead. Here goes.

You can get into problems if you mix input methods (>> and getline for example) within the same program. For example, >> doesn't remove terminating whitespace from the input buffer (In C++ input is placed in a buffer before it is placed into a variable by whatever input method you write for. This is true for at least standard input methods, anyway. There are some input methods that aren't buffered, but they aren't standard.) This means the newline char which terminates the input into bookrec.info_title is still in the input buffer when the call to getline() on the next line occurs. But the call to getline() uses the default terminating char, that is the newline char, to terminate input into the variable called authorname. Hence, since the first char in the input buffer when getline() is called is the leftover newline char from >> called before it, no information is put into authroname. (BTW, getline() does remove the terminating char (if any is found) from the input buffer.) Thus, it appears that getline() is skipped. But it's not. It's just not putting anything into authorname because it's doing what it was told to do. In addition, all input for authorname now remains in the input buffer and it may or may not be compatable with any attempt to put information into the next variable by the next input method. So the trick is to clear the input buffer after calling >> and before calling getline(). Which is what Narue's told you to do, and what the sticky she refered you tells you how to do in exciting detail. Many of us don't go to such extreme odds to clear the input buffer, which is why our programs will crash under an appropriate input scenario. Placing something like cin.ignore(80); (or some large number besides 80 if you prefer) just before any call to getline() to be sure (as you can without getting geekish about it [geekish is fine, don't get me wrong, it's just a pain in the tusch sometimes is all]) you clear the input buffer will work except in the most extremely sensitive programs (in which case you now have a wonderful reference to use, thanks to Narue).

ok tell me why flush method does not work in this case ?

here is the information from the book:

Flushing the Output Buffer
Our programs have already used the endl manipulator, which writes a newline and flushes the buffer. There are two other similar manipulators. The first, flush, is used quite frequently. It flushes the stream but adds no characters to the output. The second, ends, is used much less often. It inserts a null character into the buffer and then flushes it:

cout << "hi!" << flush;      // flushes the buffer; adds no data
    cout << "hi!" << ends;       // inserts a null, then flushes the buffer
    cout << "hi!" << endl;       // inserts a newline, then flushes the buffer

i created something like that but it didnt change anything, please explain why :

int Books::InsertBook()
{
	
	string authorName;
    cout << "id_code :" << endl;
    cin >> bookrec.id_code;
	cout << "info_title :" << endl;
	cin >> bookrec.info_title;
	cout << "author :" << endl;
	cout << flush;    getline(cin,authorName);
    int authorID = train_Author::s_add_author(authorName);
	if(authorID==0)
	{
		cout<< "Operation cancelled!" << endl;
		return 4;
	}
	bookrec.author = authorID;
	cout << "publisher :" << endl;
	cin >> bookrec.publisher;
	cout << "pubdate :" << endl;
	cin >> bookrec.pub_date;
	cout << "infotype :" << endl;
	cin >> bookrec.info_type;
	
	d_fillnew(INFO, &bookrec);
    cout << "successful" << endl;
	return 5;
}

ok tell me why flush method does not work in this case ?

here is the information from the book:

Flushing the Output Buffer
Our programs have already used the endl manipulator, which writes a newline and flushes the buffer. There are two other similar manipulators. The first, flush, is used quite frequently. It flushes the stream but adds no characters to the output. The second, ends, is used much less often. It inserts a null character into the buffer and then flushes it:

cout << "hi!" << flush;      // flushes the buffer; adds no data
    cout << "hi!" << ends;       // inserts a null, then flushes the buffer
    cout << "hi!" << endl;       // inserts a newline, then flushes the buffer

i created something like that but it didnt change anything, please explain why :

Because you're flushing the output buffer not the input buffer, is pretty much the short version of it.

Because you're flushing the output buffer not the input buffer, is pretty much the short version of it.

yeah, i just noticed that.

what i was looking is something like this :

cin.ignore(1000, '\n');

that worked for me.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.