istream_iterator игнорирует EOF (Ctrl+D) при чтении символов

Я пытаюсь использовать istream_iterator для чтения символов из cin, Я прочитал, что нажатие Ctrl+D отправляет EOF символ, который заканчивает поток ввода. К сожалению, с этим что-то не так. Вот мой код:

#include <iterator>
int main()
{
  using namespace std;

  istream_iterator<char> it(cin), eos;
  while (it != eos) clog << *(it++);
}

Я запускаю его и набираю: as df, затем нажмите Ctrl+D. Выводит только asd без последнего f а затем зависает в ожидании ввода. Когда я печатаю gh и нажмите Ctrl+D снова, он печатает оставшиеся f наконец, и g со следующего входа, но опять без последнего h, И когда я наконец нажимаю Ctrl+D, ничего не печатая, он печатает оставшиеся h и выходит.

Я ожидал это прочитать asdf и выход, так как я уже нажал Ctrl+D в конце этой первой последовательности.

Почему он все еще ждет ввода после получения EOF?
Почему не печатается последний прочитанный символ EOF?
И почему он выходит только тогда, когда я нажимаю Ctrl+D, ничего не печатая раньше?
Как нужно изменить этот цикл, чтобы он вел себя так, как я ожидаю? (т.е. прекратить чтение сразу после получения последовательности Ctrl+D на входе, независимо от того, набрал ли я что-либо раньше или нет, и чтение всех символов до EOF).

2 ответа

Решение

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

while (it != eos)
{
    clog << *it;
    it++;
}

Это позаботится о том, "Почему не печатается последний символ"

PS: что касается EOF в середине строки, это поведение, предписанное POSIX:

При получении все байты, ожидающие чтения, немедленно передаются процессу без ожидания перехода на новую строку, а EOF отбрасывается. Таким образом, если нет ожидающих байтов (то есть, EOF произошел в начале строки), нулевой счетчик байтов должен быть возвращен из read(), представляющего указание конца файла.

В Unix-подобных системах ввод Ctrl+D вызывает условие конца файла только в начале строки (т. Е. Сразу после ввода Enter. Чтобы вызвать условие конца файла в середине строки, введите Ctrl+D дважды.

Другие вопросы по тегам