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 дважды.