Почему getline не работает после cin c
Перейти к содержимому

Почему getline не работает после cin c

почему cin работает, а cin.getline — нет?

Ни один из ваших фрагментов кода не «работает» в том смысле, что оба переполняют буфер в первой строке ввода. Это совсем нехорошо.

Второй случай не ожидает ввода из-за технических различий между operator>> и getline — они по-разному реагируют на введенный вами символ новой строки. При чтении первого cin >> buffer новая строка в конце ввода остается во входном потоке ( cin ). В вашем первом случае второй cin >> buffer пропустит новую строку, которая находится во входном буфере, а затем дождется ввода дополнительных данных.

Во втором случае из-за работы getline он принимает оставшуюся новую строку в качестве ввода, а буфер ничем не заполняется.

Это обычная проблема при смешивании getline и operator>> для ввода. Лучшее решение для решения этой конкретной проблемы — использовать только operator >> или только getline — есть множество других решений, но их обычно довольно сложно найти правильно.

Оператор >> не использует пробелы, включая перевод строки. Функция getline возвращается, когда видит новую строку. Ваша проблема в новой строке, которую оператор >> оставляет в буфере. Вы можете решить эту проблему, используя все символы, включая новую строку, до тех пор, пока не увидите новую строку в буфере. См. функцию игнорирования:

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

Следовательно, символ завершения ‘\n’ уже прочитан getline() из предыдущей операции чтения. Вот почему эта функция больше не ждет ввода данных пользователем.

Попробуйте прочитать getline() перед операцией cin >> .

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

Во-первых, у вас переполнение буфера: чтение в char* останавливается, когда поток выходит из строя, обнаруживается пробел или width() исчерпан, если он был больше 0. Вы хотите использовать

Предполагая, что это неопределенное поведение существует, разница между использованием форматированного и неформатированного ввода для второго чтения состоит в том, что форматированный ввод начинается с пропуска ведущих пробелов, а неформатированный ввод — нет. Ваш первый ввод остановился прямо перед символом новой строки, полученным после нажатия клавиши ввода. Этого символа новой строки достаточно для getline() , но он пропускается при использовании >> .

При переключении между форматированным и неформатированным вводом-выводом вы обычно хотите пропустить начальные пробелы, используя, например, манипулятор std::ws :

Вам также следует рассмотреть возможность использования std::string вместе с std::getline() .

Почему после использования cin функции cin.get() и cin.getline() не работают, а последующие вызовы cin срабатывают?

Насколько я знаю cin оставляет символ ‘\n’ в потоке из-за чего последующие вызовы cin.get() и cin.getline() не будут срабатывать, поскольку они будут натыкаться на символ перевода строки и завершать свою работу. Для того, чтобы функции cin.get() и cin.getline() успешно работали после cin >> нужно «выбросить» ‘\n’ из потока при помощи cin.get() или cin.ignore(numeric_limits<streamsize>::max(), ‘\n’) .

Вопрос: почему cin будет работать и без «очищения» потока от символа ‘\n’?

Т.е. я имею в виду, что этот код будет работать без cin.get() или cin.ignore():

Если я как-то непонятно изложил суть проблемы, говорите)

user avatar

operator >> производит чтение с разделением по пробельным символам и при вызове будет сначала пропускать эти символы, пока не дойдет до текста. getline производит чтение до конца строки.

Использование getline (cin, s) после cin

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

С до getline() команда однако (что, как я предполагаю, является проблемой), это не позволит мне вводить имена. Почему?

Я слышал что-то об , но я понятия не имею, как это работает и почему это даже необходимо.

12 ответов

в коде выше, этот бит.

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

почему бы просто не использовать ignore?

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

Итак, когда бы вы использовали clear и ignore?

и std::cin.clear() (и std::cin.igore() ) не требуется, но полезно для устранения состояния ошибки. Например, если вы хотите дать пользователю много шансов ввести допустимый номер.

не может ли это быть проще с skipws или подобным?

еще один простой, но новоиспеченные альтернативы ignore для вашего первоначального требования использует std::skipws пропустить любое количество пробелов перед чтением линий.

. но если он получает входные данные, такие как» 1E6 » (например, какой-то ученый пытается ввести 1,000,000, но C++ поддерживает только эту нотацию для чисел с плавающей запятой), не примет этого, вы получите number значение 1 и E6 читать как первое значение name . Отдельно, если у вас есть действительный номер, за которым следует один или несколько пустые строки, эти строки будут проигнорированы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *