c++ getline() isn't waiting for input from console when called multiple times

这一生的挚爱 提交于 2019-11-26 18:56:26

The problem is you are mixing calls to getline() with the use of the operator >>.

Remember that operator >> ignored leading white space so will correctly continue across lines boundaries. But stops reading after the input has successfully been retrieved and thus will not swallow trailing '\n' characters. Thus if you use a getline() after a >> you usually get the wrong thing unless you are careful (to first remove the '\n' character that was not read).

The trick is to not use both types of input. Pick the appropriate one and stick to it.

If it is all numbers (or objects that play nice with operator >>) then just use operator >> (Note string is the only fundamental type that is not symmetric with input/output (ie does not play nicely)).

If the input contains strings or a combination of stuff that will require getline() then only use getline() and parse the number out of the string.

std::getline(std::cin, line);
std::stringstream  linestream(line);

int  value;
linestream >> value;

// Or if you have boost:
std::getline(std::cin, line);
int  value = boost::lexical_cast<int>(line);

You need to flush the input buffer. It can be done with cin.clear(); cin.sync();.

You can use

cin.ignore();

or as @kernald mentioned use

cin.clear();
cin.sync();

before using getline()

Use cin.clear() as mentioned and use proper error handling:

    cin.clear();
    cin.sync();

    cout << "Title: "; 
    if (!getline(cin, inputString))  exit 255;
    tempDVD.setTitle(inputString);

    cout << "Category: "; 
    if (!getline(cin, inputString))  exit 255;
    tempDVD.setCategory(inputString);

    cout << "Duration (minutes): "; 
    if (!(cin >> inputUInt)) exit 255; 
    tempDVD.setDuration(inputUInt);

    cout << "Year: "; 
    if (!(cin >> inputUInt)) exit 255; 
    tempDVD.setYear(inputUInt);

    cout << "Price: $"; 
    if (!(cin >> inputDouble)) exit 255; 
    tempDVD.setPrice(inputDouble);

If user inputs a space before \n in previous cin before getline, only ignore itself wouldn't be enough so you have to use this code instead of ignore() alone. For example 12345 \t \n will not work anymore. All unprocessed characters must be ignored.

#include <limits>
cin.ignore(numeric_limits<streamsize>::max(), '\n');

Use this between cin and getline.

Mixing getline() with input streams in generally a bad thing to do. It's theoretically possible to manually handle the dirty buffers left over by using streams, but it's an unnecessary pain that should definitely be avoided.

You are better off using a console library to grab your input, this way the dirty-work can be abstracted for you.

Take a look at TinyCon. You can just use the static method tinyConsole::getLine() in replace of your getline and stream calls, and you can use it as many times as you'd like.

You can find information here: https://sourceforge.net/projects/tinycon/

cin.sync(); use this instead of cin.ignore( works best.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!