getline falling through

I have this bit of code that's suppose to capture a string entry:

1
2
3
4
5
6
7
void setTitle() {
  string s;
  cout << "Book Title: ";
  getline(cin, s);
  
  title.emplace_back(s);
}


It never stops for Book Title input. Just sails right on through.

What am I doing wrong?
Hello Slyde,

You may think this is where the problem begins, but it does not. There is not enough code to say where it starts, but something you could try is to put this:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>. before the getline.

I would guess that somewhere before this function you did std::cin >> someVariable;. This leaves the new line (\n) in the buffer, so when you get to the "std::getline" it takes whatever is left in the buffer and moves on without waiting for any input.

Andy
WOW! Worked like a charm.

But this has even more confused: others have tested the code and they say it works for them. Is this a compiler thing?

And thank you very much for the insight.

EDIT: I see what you're talking about. The function comes on the heals of a Menu selection. So I guess the std::cin garbage was going into the std::cin in the function.

1
2
3
4
5
6
7
8
9
10
do {
       cout << "\nA)dd a book";
       cout << "\nC)heckout a book";
       cout << "\nQ)uit";
       cout << "\n--------------\n";
       cin >> sel;
       sel = toupper(sel);
    } while (sel != 'Q' && sel != 'A' && sel != 'C');
    if (sel == 'A')
        bks.setTitle();
Last edited on
Hello Slyde,


But this has even more confused: others have tested the code and they say it works for them. Is this a compiler thing?


That makes 2 of us. The question to ask is what compiler they used or where they compiled and ran the program. Was it their computer or onlike?

There are 2 types of input; formatted and unformatted. Formatted input something like: std::cin >> menuChoice; will take what you type and put it into a buffer, usually referred as the input buffet, and wait until you press "Enter". Then it will attempt to put you input into the variable, but it leaved the new line (\n) in the buffer. If followed by another std::cin >> something; this is not a problem because the "std::cin" will ignore any white space including the (\n).

The unformatted input, the "std::getline()" will extract the entire contents of the buffer including the (\n) which it discards leaving the buffer empty.

So when your program mixes formatted input with unformatted input you can usually follow the input with std::cin.ignore();. This will ignore the (\n) left in the buffer. If it should be a problem the line I showed you is considered the most portable way.

Sometimes when you are not sure where the last formatted input is putting the ignore before the "std::getline" works.

Given your menu code try using "std::cin.ignore():" after line 6 or 7 and see what you get.

Andy
The unformatted input, the "std::getline()" will extract the entire contents of the buffer including the (\n) which it discards leaving the buffer empty.

std::getline() input will extract the contents of the buffer from the current position up to and including the specified termination char (default \n) or the end of the buffer if no termination char is found. The termination char is then discarded if present. The rest of the buffer remains for future input. The buffer may or may not be empty afterwards.
@Handy Andy & seeplus:

Thanks for the insight. It put clarity to a head-scratcher.

I replaced std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); with std::cin.ignore(); and it worked fine. So that's enough to clear the buffer of '\n'.

I'm having a blast learning C++. And to come here for insight and the responses all be positive is huge for me. Thank you again for your help, both of you.
Last edited on
.ignore() will clear one char from the buffer. As sel is of type char and the user inputs say abc then >> will retrieve the a leaving bc/n in the buffer. .ignore() will remove the b leaving c/n in the buffer! So the next input will retrieve the c ! That's why the std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') is used. This will remove all chars preceding the '\n and the '\n' - removing any unwanted remaining chars.
Topic archived. No new replies allowed.