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

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

  • автор:

 

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

Hi I just wonder why can’t the program run as it is supposed to.
Could anyone explain how it really work? THX!

I gather the output of s is always blank? the extraction operator >> ignores whitespace characters but getline() does not. A new line character remains in the stream after your first input.

Use cin.sync() before getline() to clear the input stream.

cin.sync() isn’t required to do anything useful.

Use cin.ignore( numeric_limits <streamsize> ::max(), ‘\n’ ); after cin >> foo; .

Hope this helps.

before the get line, it works normally.

but how does cin.get() work?

Well Im new too, but when looking at your code, The first thing I noticed was that if that was to run.

Your program will run, then go off before you got to see it work. you would need a
system ( «pause» );

before the return to get it to stop,

as in for the difference between the two, for output, on a monitor, nothing as far I noticed, but when putting output to a file eg «.txt.» for fstreams

then you will need getline to identify which string variable your dealing with.

Also, the output should not vary if you change the standard streams to file(s). If it does, your compiler is broken.

Side Note: like I said, Im new to this as well, just to make sure I understand what I read, its bad to use System «Pause»; because its only a windows related problem?.

Im sorry I just want to make sure I know why its bad, and what would be a better solution to that problem?

Duoas wrote:
cin.sync() isn’t required to do anything useful.

Could you explain what you mean by this? and link to any relevant articles.. I’ve googled around but don’t see any information regarding such an issue.

-edit-

Nvm! found an informative post here:-

It actually (at least for buffered istreams) will discard unread characters. Unless I’m misreading something.

IIRC, the standard doesn’t actually require sync() to do anything — and most implementations don’t.

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

Нет, это не так; он записывается за конец буфера, повреждая память и вызывая неопределенное поведение. Может показаться, что это работает для вас, если в поврежденной памяти не окажется ничего важного; но в принципе могло случиться все что угодно. — Mike Seymour

4 ответы

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

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

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

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

 

значит ли это, что это произойдет только один раз после переполнения буфера для cin.getline, в следующий раз getline будет ждать ввода? — Сингх

Предполагая, что вы НЕ переполняете буфер, следующая строка getline должна работать. Поскольку вы переполняете буфер, кто знает, что перезаписывается и что происходит — это называется неопределенным поведением, и это действительно означает, что «может произойти что-то странное». Вы проверили, что ваш cin Например, поток не находится в состоянии ошибки? — Матс Петерссон

Что-то вроде if (cin) cout << «Error on cin\n»; сделал бы это. — Матс Петерссон

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

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

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

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

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

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

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

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

но даже если после этого я добавлю цикл некоторое время. он продолжает выполняться каждый раз и никогда не ждет ввода.. — Сингх

Вы пытались внести изменения, которые я предложил? — Абхишек Бансал

я хочу знать причину такого поведения. поэтому я использую эту последовательность — Сингх

@singh посмотри это. cplusplus.com/reference/string/string/getline/?kw=getline Из ссылки видно, что getline завершается символом EOL. Этот символ EOL считывается функцией getline() перед вашим вторым вводом, потому что вы нажимаете клавишу ввода при вводе первого ввода. Этот ‘enter’ не читается cin, а остается во входном буфере. — Абхишек Бансал

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

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

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

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

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

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

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


Return to Topic Menu | Computer Science Main Page | MathBits.com | Terms of Use

Problems with getline(cin, name);

Since getline does not ignore leading whitespace characters, you should take special care when using it in conjunction with cin >> .

The problem: cin>> leaves the newline character (\n) in the iostream. If getline is used after cin>> , the getline sees this newline character as leading whitespace, thinks it is finished and stops reading any further.

Program fragment with problem:

apstring name;
int age;

OUTPUT:
Enter your age 5
Enter your full name Ben Bunny
, you are 5


The yellow wave is the iostream. The cin statement uses the 5 and leaves the \n in the stream as garbage. The cin statement will NOT read (or "grab") \n. The cin also ignores \n when reading data. The getline, on the other hand, reads and "grabs" \n. So, when it sees the \n LEFT from cin, it "grabs" the \n and thinks it is finished reading.

Don’t be a dumb bunny and fall for this trap.

Ways to fix the problem:

Consume the trailing newline character from the cin>> before calling getline, by "grabbing" it and putting it into a "dummy" variable.
You will see me using this method throughout the course.

apstring dummy;
getline(cin, dummy);

Program fragment with correction:

apstring name, dummy;
int age;

cout<<"Enter your age";
cin>>age;
getline(cin,dummy);
cout<<"Enter your full name";
getline(cin, name);

OUTPUT:
Enter your age 5
Enter your full name Ben Bunny
Ben Bunny, you are 5

 

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

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