Я обычно учу своих учеников, что безопасный способ ввода файлов:
while (true) {
// Try to read
if (/* failure check */) {
break;
}
// Use what you read
}
Это спасло меня и многих людей от классической и большую часть времени ошибалось:
while (!is.eof()) {
// Try to read
// Use what you read
}
Но людям действительно нравится эта форма зацикливания, поэтому стало привычным видеть это в коде ученика:
while (is.peek()!=EOF) { // <-- I know this is not C++ style, but this is how it is usually written
// Try to read
// Use what you read
}
Теперь вопрос: есть ли проблема с этим кодом? Есть ли случаи, когда все работает не так, как ожидалось? Хорошо, это два вопроса.
РЕДАКТИРОВАТЬ ДОПОЛНИТЕЛЬНЫЕ ДАННЫЕ: во время экзаменов вы иногда гарантируете учащимся, что файл будет правильно отформатирован, поэтому им не нужно делать все проверки и просто нужно проверить, есть ли еще данные. И большую часть времени мы имеем дело с двоичными форматами, которые позволяют вам вообще не беспокоиться о пробелах (потому что все данные значимы).
Хотя принятый ответ является совершенно ясным и правильным, я все же хотел бы, чтобы кто-то попытался прокомментировать совместное поведение peek()
и unget()
.
Материал unget()
пришёл мне в голову, потому что я однажды заметил (я думаю, что это было на Windows), что, посмотрев на ограничение внутреннего буфера 4096 (так эффективно вызывая загрузку нового буфера), не удалось получить предыдущий байт (последний из предыдущего буфера). Но я могу ошибаться. Так что это было мое дополнительное сомнение: что-то известное, что я пропустил, что, возможно, хорошо закодировано в стандарте или в некоторых реализациях библиотеки.