istream_iterator игнорирует EOF (Ctrl + D) при чтении символов - PullRequest
3 голосов
/ 07 сентября 2011

Я пытаюсь использовать 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 ]

6 голосов
/ 07 сентября 2011

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

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

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

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

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

3 голосов
/ 07 сентября 2011

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

...