c++ getline() не ожидает ввода из консоли при вызове несколько раз

Я пытаюсь получить несколько параметров пользовательского ввода из консоли, две строки,два ввода и двойной. Соответствующий код, который я пытаюсь использовать, таков:

#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);

однако при запуске программы вместо ожидания ввода первой строки inputString код не останавливается до второго вызова getline (). Таким образом, вывод консоли выглядит следующим образом:

Название: Категория:

с курсором появляется после разряда. если я теперь программа переходит к вводу года, не позволяя мне вводить более одной строки. Что здесь происходит?

6 ответов


проблема в том, что вы смешиваете вызовы getline() с использованием оператора >>.

помните, что оператор > > игнорировал ведущее пустое пространство, поэтому будет правильно продолжать пересекать границы линий. Но прекращает чтение после успешного извлечения ввода и, таким образом, не будет проглатывать конечные символы "\n". Таким образом, если вы используете getline () после a >> вы обычно получаете неправильную вещь, если вы не осторожны (сначала удалите символ' \n', который не был читать.)

фокус в том, чтобы не использовать оба типа ввода. Выберите подходящий и придерживайтесь его.

Если это все числа (или объекты, которые хорошо играют с оператором>>), то просто используйте оператор > > (строка Примечания-единственный фундаментальный тип, который не симметричен входу/выходу (т. е. не играет хорошо)).

если вход содержит строки или комбинацию вещей, которые потребуют getline (), то используйте getline () и разберите число из строка.

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);

вам нужно очистить входной буфер. Это можно сделать с помощью cin.clear(); cin.sync();.


можно использовать

cin.ignore();

или как @ kernald упомянул использование

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

перед использованием getline ()


использовать cin.clear() Как уже упоминалось и использовать правильную обработку ошибок:

    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);

смешивание getline () с входными потоками, как правило, плохо. Теоретически можно вручную обрабатывать грязные буферы, оставшиеся с помощью потоков, но это ненужная боль, которую определенно следует избегать.

вам лучше использовать консольную библиотеку, чтобы захватить ваш ввод, таким образом, грязная работа может быть абстрагирована для вас.

взгляните на TinyCon. Вы можете просто использовать статический метод tinyConsole:: getLine () в замене вашей getline и поток вызовов, и вы можете использовать его столько раз, сколько захотите.

вы можете найти здесь информацию : https://sourceforge.net/projects/tinycon/


cin.синхронизация(); используйте это вместо cin.игнорировать( хорошо работать.