'c++ getline() isn't waiting for input from console when called multiple times
I'm attempting to get a few user-input parameters from the console, two strings, two ints and a double. The relevant code I'm trying to use is this:
#include <string>
#include <iostream>
using namespace std;
// ...
string inputString;
unsigned int inputUInt;
double inputDouble;
// ...
cout << "Title: ";
getline(cin, inputString);
tempDVD.setTitle(inputString);
cout << "Category: ";
getline(cin, inputString);
tempDVD.setCategory(inputString);
cout << "Duration (minutes): ";
cin >> inputUInt;
tempDVD.setDuration(inputUInt);
cout << "Year: ";
cin >> inputUInt;
tempDVD.setYear(inputUInt);
cout << "Price: $";
cin >> inputDouble;
tempDVD.setPrice(inputDouble);
However, when running the program, instead of waiting for the first inputString to be entered, the code doesn't stop until the second getline() call. Thus the console output looks like this:
Title: Category:
with the cursor appearing after category. If I input now, the program then jumps ahead to the year input, not allowing me to enter more than one string. What's happening here?
Solution 1:[1]
You need to flush the input buffer. It can be done with cin.clear(); cin.sync();.
Solution 2:[2]
You can use
cin.ignore();
or as @kernald mentioned use
cin.clear();
cin.sync();
before using getline()
Solution 3:[3]
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);
Solution 4:[4]
Also works with ws. You can use getline(cin >> ws, inputString)) to eat the whitespaces or the newlines after reading data with cin command.
Solution 5:[5]
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.
Solution 6:[6]
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/
Solution 7:[7]
cin.sync(); use this instead of cin.ignore( works best.
Solution 8:[8]
The function_______ will return the last read character and will move the inside pointer one with -1 char.
- Getline()
- Peek() 3.flush() 4.putback()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Marc Plano-Lesay |
| Solution 2 | Hossein |
| Solution 3 | |
| Solution 4 | Osman Coskun |
| Solution 5 | |
| Solution 6 | Unix-Ninja |
| Solution 7 | Gurudev |
| Solution 8 | Abhishek Verma |
