Проблема использования cin дважды

Вот код:

string str;
cin>>str;
cout<<"first input:"<<str<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;

Результат состоит в том, что getline никогда не приостанавливаются для ввода данных пользователем, поэтому второй вывод всегда пуст.

После проведения некоторого времени на нем я понял после первого вызова "cin>> ул.", кажется, что '\n' все еще хранится в cin (использующий cin.peek () для проверки), который сразу заканчивает getline. Решение будет добавлять еще одну строку между первым использованием и вторым: cin.ignore(numeric_limits::max(), '\n');

Однако я все еще не понимаю, почему '\n' оставлен там после первого вызова? Что делает istream& оператор>>, действительно делают?

8
задан gc . 26 March 2010 в 17:30
поделиться

5 ответов

Хорошая запись, объясняющая некоторые причины, по которым вы столкнулись с этой проблемой, в первую очередь из-за поведения типов входных данных и того, что вы их смешиваете

0
ответ дан 5 December 2019 в 14:02
поделиться

\ n остается во входном потоке в соответствии с тем, как оператор >> определен для std :: string . std :: string заполняется символами из входного потока до тех пор, пока не будет найден пробельный символ (в данном случае \ n ), после чего заполнение прекращается и пробел теперь следующий символ во входном потоке.

Вы также можете удалить \ n , вызвав cin.get () сразу после cin >> str . Однако есть много-много разных способов снять шкуру с этой конкретной кошки ввода-вывода. (Может быть, это хороший вопрос сам по себе?)

7
ответ дан 5 December 2019 в 14:02
поделиться

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

std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
2
ответ дан 5 December 2019 в 14:02
поделиться

По умолчанию оператор вставки потока читает, пока не видит пробел. Ваш первый вызов не возвращается, пока не увидит пробел, табуляцию, новую строку и т. Д. Затем необходимо использовать следующий символ, чтобы вы могли перейти к следующему.

1
ответ дан 5 December 2019 в 14:02
поделиться

Я вообще рекомендую делать только линейно-ориентированный ввод из std::cin. Таким образом, ваш код может выглядеть примерно так:

string str;
int val;
// Read an entire line and parse an integer from it
{
    string line;
    getline(cin, line);
    istringstream iss(line);
    iss >> val;
}
cout<<"first input:"<<val<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;

Не забудьте добавить проверку ошибок.

Подход getline-only позволяет избежать необходимости думать о буферизации ввода по строкам, об очистке ввода и т.д. Если вы напрямую читаете что-то с помощью >>, ввод не прерывается, если пользователь нажимает enter вместо ввода требуемого, а продолжается до тех пор, пока не будет введена лексема (такое поведение обычно нежелательно).

2
ответ дан 5 December 2019 в 14:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: