Cin становится пропущенным после использования в течение цикла - PullRequest
0 голосов
/ 07 июня 2019

Просто написал 3-4 строки, чтобы воспроизвести проблему. После использования cin >> внутри цикла for для многократного ввода, все последующие cin >> (s) всегда пропускаются.

Все, что угодно, кроме cin, работает нормально (просто хочу знать, почему это происходит и что мне делать, чтобы иметь возможность использовать cin далее в программе)

for(int x;cin >> x;){
        cout << x <<endl;
}
int a;
cin >>a;

Нет сообщения об ошибке.

Ответы [ 2 ]

5 голосов
/ 07 июня 2019

Что бы вы ни делали, чтобы cin >> x потерпел неудачу (чтобы разорвать цикл), это также повлияет на cin >> a, поскольку это та же самая команда dang!

Объект cin не делает "не знает о вашей логике цикла, и ваша операционная система / терминал также не знает, что вы предполагаете, что после сбоя цикла произойдет какой-то «сброс».Вы должны были бы сигнализировать об этом сами.Однако, вероятно, вы не можете просто исправить это, потому что:

  • Если вы нажмете Ctrl + C, чтобы завершить программу, то программа завершится.
  • Если вы нажмете Ctrl+ D (Linux / macOS) или Ctrl + Z (Windows), тогда вы задали для потока условие «конец файла», и он больше не будет принимать.У объекта std::cin будет установлен флаг EOF, и это сохраняется.(Иногда вы можете очистить это вручную, но я бы не рекомендовал это делать, так как вы можете запутаться на стороне отправителя, в зависимости от вашей платформы…)

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

0 голосов
/ 07 июня 2019

Второе выражение в заголовке for является условием цикла; цикл будет продолжаться до тех пор, пока это правда. Ваше условие всегда верно, поэтому цикл никогда не завершается.

Вы можете добавить код в свой цикл, например, чтобы выйти из него. if (x == 0) break;

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

Как >> работает

Для std::basic_istream (std::cin является одним из них), оператор >> переопределяется для реализации извлечения отформатированных данных и предназначен для цепочки (например, cin >> a >> b >> c). Это работает, потому что:

  1. >> является левоассоциативным, поэтому он группируется как ((cin >> a) >> b) >> c)
  2. >> возвращает ссылку на объект потока, поэтому вы можете продолжать добавлять >> столько, сколько хотите.

Кроме того, std::basic_istream может быть преобразовано в bool и будет true, если не возникло ошибок. Таким образом, ваше условие цикла всегда cin, и, поскольку вы, вероятно, не получаете ошибок, всегда верно.

...