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

Как подружить cin и cin.getline

Ребят, я просто сломал себе голову.

После того, как выбираешь пункт меню (1 или 2). Например нажимаешь добавить фильмы, Первый getline игнорируется, как будто в буфере остался текст и уже записался. Сразу просит ввести «режиссера», вводим например «test» и далее вводим «test2». Затем нажимаем показать все фильмы и в поле режиссер и жанр видим какие-то непонятные символы.

Но, если при запуске программы, вначале мы зайдем «показать все фильмы» а затем добавим запись, то при повторном вызове «показать все фильмы» строки заполнятся корректно. Что это вообще такое?

Также, если раскомментировать ввод рейтинга и цены(cin>>. ), при добавлении фильма, то результаты весьма странные могут быть.

В чем проблема моих бед и как посоветуете это победить?

1 ответ 1

Я взял на себя смелость, переписать на чистом С. Этот код не идеальный, но для сдачи в ВУЗе думаю будет предостаточно.

Переписывая код, я понял, почему плохо отрабатывал ввод. У Вас выделен массив на два элемента, а в процессе ввода Вы его не увеличивали. В результате, оно писало данные за пределы массива, а это может приводить к чему угодно (на самом то деле, к чему оно приведет, предсказать можно для каждого конкретного случая, учитывая компилятор, операционку и текую фазу Луны).

студийный компилятор может ругаться на некоторые функции и предлагать заменить их его любимыми аналогами с _s на конце. Это его личные тараканы и если Вам нужно будет запустить код под студией, переделывайте самостоятельно. С помощью gcc и clang код компилируется без единой ошибки на максимальном уровне паранойи ( -Wall -Wextra -pedantic ).

Также, в коде используются fgets вместо gets. gets на данный момент считается дурным тоном — он не проверяет размер вводимых данных и может организовать переполнение.

Ещё в коде есть goto. Да, некоторые начитавшись Дейкстры, начали кричать во все горло, что goto это плохо. Но проблема не в goto, а в пишущем.

Источник

Использование 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 . Отдельно, если у вас есть действительный номер, за которым следует один или несколько пустые строки, эти строки будут проигнорированы.

Источник

getline() не работает, если используется после некоторых входов

getline() не работает, если я использую его после некоторых входов, т. е.

где, как если бы я использовал getline() поверх входных данных, это действительно работает, т. е.

В чем может быть причина?

3 ответа

По какой-то странной причине функция getline() работает не так, как должна. У меня есть цикл программы через рекурсию (return main();). При первом запуске следующего кода все в порядке. cout let a = putStrLn getLine делает такую ошибку. :1:17: Couldn’t match expected type `String’ against inferred type `IO String’ In the first argument of `putStrLn’, namely `getLine’ In the expression: putStrLn.

Символы извлекаются до тех пор, пока не будут извлечены символы (n — 1) или не будет найден символ-разделитель (который является разделителем, если указан этот параметр, или «\n » в противном случае). Извлечение также останавливается , если в последовательности ввода достигнут конец файла или если во время операции ввода возникает ошибка.

Когда cin.getline() считывается с входных данных, во входном потоке остается символ новой строки, поэтому он не считывает вашу c-строку. Используйте cin.ignore() перед вызовом getline() .

Добавление к тому, что сказал @DavidHammen:

Операции извлечения оставляют символ trailing ‘\n’ в потоке. С другой стороны, istream::getline() отбрасывает его. Поэтому, когда вы вызываете getline после оператора извлечения, ‘\n’ -это первый символ, который он встречает, и он сразу же перестает читать.

Читайте также:  Пианино как починить западающую клавишу

Поставьте это после перед извлечением вызова getline :

Более надежным способом получения входных данных было бы что-то вроде этого:

Вы не проверяете статус потока. Оператор извлечения потока std::cin ( operator>> ) может выйти из строя. Когда это происходит, поток помечается как «bad» ( заданы failbit , badbit или eofbit ). После «bad» все последующие извлечения потока в этом потоке завершатся неудачей, если вы не очистите статус.

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

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

Прочитав много тем о том, что getline пропускается, я все еще не могу заставить свою программу работать. Сначала я прочитал ввод пользователя. Это должно быть что-то вроде ADD 1. Затем я показываю.

#include #include using namespace std; int main() < int num; string str; cout >num; cout > table [i][j]; Я хочу внести некоторые изменения.

По какой-то странной причине функция getline() работает не так, как должна. У меня есть цикл программы через рекурсию (return main();). При первом запуске следующего кода все в порядке. cout.

Я полный новичок на Haskell. Мой сценарий Haskell с GHCi , Prelude> let a = putStrLn getLine делает такую ошибку. :1:17: Couldn’t match expected type `String’ against inferred.

Я написал программу C++, в которой в качестве входных данных используется несколько файлов CSV, которые я открываю по одному и закрываю после извлечения данных в выходной файл, который является.

карта-это файл, который я открыл. строка-строка Верхняя часть работает, а нижняя-нет. getline(map, line); getline(ssvalues, values, ‘|’); // Gets the name of the tileset file.

Я использую getline для получения строкового ввода от пользователя, как показано ниже. cout > fullname; cin.ignore(); getline(cin, fullname); getline работает.

Я хочу держать строку с пробелами, поэтому я использовал getline() , но после нее я хочу получить другую строку (без пробелов), если есть, например, -e и строка после нее в s2 , но так как в моем.

Источник

Почему функция getline () ничего не читает здесь?

Программа должна распечатать,

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

Решение

После выполнения этого заявления:

следующая вещь во входном потоке — это символ новой строки, который не используется при чтении int в E , Итак, первый звонок getline(cin, edge) просто читает до этого символа новой строки, который является пустой строкой.

Читайте также:  Обид не работает телевизор

Вам нужно прочитать больше данных из потока, чтобы первый вызов getline читает новую строку, а не то, что осталось после прочтения N а также E ,

Вы можете сделать это так:

Это будет читать до новой строки в фиктивной переменной, поэтому следующее чтение начинается со следующей строки.

Это скажет cin Поток, чтобы сбросить символы, пока либо:

  • он прочитал std::numeric_limits ::max() символы (это очень очень большое число), или
  • это читает \n символ (то есть следующий символ новой строки).

Опять же, это означает, что следующее чтение начнется со следующей строки.

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

Это просто отбросит максимум 20 символов или следующий символ новой строки, в зависимости от того, что произойдет раньше.

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

Это должно работать для вашего случая, но немного более хрупко, потому что, если кто-то вставит пробел в ваш входной файл, все снова перестанет работать.

Источник

С++ метод getline не работает

Извините, но я совершенно новый для C++, но не для программирования вообще. Поэтому я попытался сделать простое шифрование/дешифрование. Однако, когда я добавил модификацию к моему предыдущему коду (поэтому нет двух программ для шифрования и дешифрования), я обнаружил, что метод ‘getline()’ больше не работает. Вместо этого он просто игнорирует это при запуске кода. Здесь код:

Это потому, что std::cin >> op; оставляет в вашем коде висящий \n , и это первое, что читает getline . Поскольку getline перестает читать, как только находит символ новой строки, функция возвращается немедленно и больше ничего не читает. Вы должны игнорировать этот символ, например, используя cin.ignore(std::numeric_limits ::max(), ‘\n’); ( std::numeric_limits определяется в заголовке
), как указано в cppreference.

Это связано с тем, что у вас все еще есть символ новой строки в буфере, который заставляет getline() останавливать чтение, как только он встретится с ним.

Используйте cin.ignore() чтобы игнорировать символ новой строки из буфера. Это будет сделано в вашем случае.

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

cin.ignore( std::numeric_limits ::max(), ‘\n’ );

есть новые строки из предыдущего ввода std::cin >> op;

Как уже было сказано, форматированный вход (используя in >> value ) начинает пропускать пробел abd stop, когда они будут выполнены. Обычно это приводит к тому, что некоторые пробелы пробегают. При переключении между форматированным и неформатированным входом вы обычно хотите избавиться от ведущего пространства. Это можно легко сделать с помощью манипулятора std::ws :

Источник

Оцените статью