- Как подружить cin и cin.getline
- 1 ответ 1
- Использование getline (cin, s) после cin
- 12 ответов
- почему бы просто не использовать ignore?
- Итак, когда бы вы использовали clear и ignore?
- не может ли это быть проще с skipws или подобным?
- getline() не работает, если используется после некоторых входов
- 3 ответа
- Похожие вопросы:
- Почему функция getline () ничего не читает здесь?
- Решение
- С++ метод getline не работает
Как подружить 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 :
Источник