istream :: заглянуть в любопытное поведение EOF - PullRequest
2 голосов
/ 07 января 2012

Я только что столкнулся с любопытной ситуацией в C ++.Я делал что-то вроде:

istream in;
// ...
in.get();      // get a char (which turns out to be the last)
               // curiously ios::eof bit doesn't get set just yet

c = in.peek(); // attempt to peek, return EOF and now set ios::eof bit

if(c == EOF) {
    // realize shouldn't have gotten the last char for some reason
    in.unget(): // attempt to unget, *fails* (because ios:eof bit was set)
}

Теперь мне любопытно, почему peek устанавливает бит eof;Я нахожу это крайне не интуитивным.Предполагается, что он просто смотрит, не потребляет ничего и не должен изменять состояние потока.Кроме того, почему unget впоследствии не работает?Стандарт обязывает все операции быть nop, когда good() ложно или что-то?

1 Ответ

4 голосов
/ 07 января 2012
in.get();      // get a char (which turns out to be the last)
               // curiously ios::eof bit doesn't get set just yet

Это не "любопытно".Бит EOF потока устанавливается, когда чтение завершается неудачно из-за достижения значения eof ; не означает «последнее чтение привело нас к eof».

c = in.peek(); // attempt to peek, return EOF and now set ios::eof bit

Как сейчас.

Кроме того, почемуunget впоследствии не работает?Стандарт обязывает все операции быть nop, когда good() ложно или что-то?

... что и происходит.В противном случае вы не смогли определить «не работает».

При достижении EOF вам придется самостоятельно очищать состояние потока, если вы хотите unget получить тот символ, который вы получили в строке 3.

istream in;
// ...
in.get();      // assume this succeeds (*)

c = in.peek(); // assume this fails and sets EOF bit

if (!in) {
   in.clear(); // clear stream error state for use
   in.unget(); // "put back" that character (*)
}
else {
   // next char from .get() will be equal to `c`
}
...