istream::peek 好奇的行为。 EOF

发布于 2024-12-25 11:25:06 字数 602 浏览 1 评论 0原文

我刚刚在 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 随后不起作用?当 good() 为 false 或其他情况时,标准是否要求所有操作都为 nop?

I've just encountered a curious situation in C++. I was doing something like:

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)
}

Now I'm curious why peek sets the eof bit; I find this highly unintuitive. It's supposed to just peek not actually consume anything and shouldn't change the stream state. Also, why unget subsequently doesn't work? Does the standard mandates all operations to be nop when good() is false or something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听,心雨的声音 2025-01-01 11:25:06
in.get(); // 获取一个字符(结果是最后一个)
               // 奇怪的是 ios::eof 位还没有被设置

这并不“好奇”。当读取由于达到 eof 而失败时,流的 EOF 位将被设置;它确实意味着“最后一次读取将我们带到了eof”。

c = in.peek(); // 尝试查看,返回 EOF 并且现在设置 ios::eof 位

就像现在一样。

另外,为什么 unget 随后不起作用?当 good() 为 false 或其他情况时,标准是否要求所有操作都为 nop?

...这就是正在发生的事情。您未能以其他方式定义“不起作用”。

如果您想取消在第 3 行检索到的字符,则必须在到达 EOF 时自行清除流的状态。

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`
}
in.get();      // get a char (which turns out to be the last)
               // curiously ios::eof bit doesn't get set just yet

This is not "curious". The stream's EOF bit gets set when a read fails due to having reached eof; it does not mean "the last read took us to eof".

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

Like now.

Also, why unget subsequently doesn't work? Does the standard mandates all operations to be nop when good() is false or something?

... which is what's happening. You failed to otherwise define "doesn't work".

You'll have to clear the stream's state yourself when EOF was reached, if you want to unget that character you retrieved on line 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`
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文