C++: std::istream 检查 EOF 而不读取/消耗令牌/使用运算符>>

发布于 2024-11-03 06:15:41 字数 732 浏览 2 评论 0原文

我想测试 std::istream 是否已到达末尾而不从中读取。

我知道我可以这样检查 EOF:

if (is >> something) 

但这有一系列问题。想象一下,有许多(可能是虚拟的)方法/函数期望 std::istream& 作为参数传递。 这意味着我必须做“家务”,检查每个变量中的 EOF,可能使用不同类型的 something 变量,或者创建一些奇怪的包装器来处理调用输入方法的场景。

我需要做的就是:

if (!IsEof(is)) Input(is);

方法IsEof应该保证流的读取不会改变,这样上面的行就相当于:

Input(is)

对于Input中读取的数据代码>方法。

如果没有通用的解决方案可以表示 std::istream ,是否有任何方法可以为 std::ifstream 或 cin 做到这一点>?

编辑: 换句话说,以下 assert 应始终通过:

while (!IsEof(is)) {
  int something;
  assert(is >> something);
}

I would like to test if a std::istream has reached the end without reading from it.

I know that I can check for EOF like this:

if (is >> something) 

but this has a series of problems. Imagine there are many, possibly virtual, methods/functions which expect std::istream& passed as an argument.
This would mean I have to do the "housework" of checking for EOF in each of them, possibly with different type of something variable, or create some weird wrapper which would handle the scenario of calling the input methods.

All I need to do is:

if (!IsEof(is)) Input(is);

the method IsEof should guarantee that the stream is not changed for reading, so that the above line is equivalent to:

Input(is)

as regards the data read in the Input method.

If there is no generic solution which would word for and std::istream, is there any way to do this for std::ifstream or cin?

EDIT:
In other words, the following assert should always pass:

while (!IsEof(is)) {
  int something;
  assert(is >> something);
}

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

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

发布评论

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

评论(5

雾里花 2024-11-10 06:15:41

istream 类有一个 eof 位,可以使用is.eof() 成员。

编辑:所以您想查看下一个字符是否是 EOF 标记而不将其从流中删除? if (is.peek() == EOF) 可能就是您想要的。请参阅 istream::peek 的文档

The istream class has an eof bit that can be checked by using the is.eof() member.

Edit: So you want to see if the next character is the EOF marker without removing it from the stream? if (is.peek() == EOF) is probably what you want then. See the documentation for istream::peek

情痴 2024-11-10 06:15:41

那是不可能的。 IsEof 函数如何知道您要读取的下一个项目是 int?

以下内容是否也不会触发任何断言?

 while(!IsEof(in))
 {
    int x;
    double y;
    if( rand() % 2 == 0 )
    {
       assert(in >> x);
    } else {
       assert(in >> y);
    }
 }

也就是说,您可以使用 exceptions 方法将“内务管理”保留在一个地方。

而不是

   if(IsEof(is)) Input(is)

try

   is.exceptions( ifstream::eofbit /* | ifstream::failbit etc. if you like */ )
   try {
     Input(is);
   } catch(const ifstream::failure& ) {
   }

它不会阻止您在“为时已晚”之前阅读,但它确实避免了所有函数中都需要有 if(is >> x) if(is >> y) 等。

That's impossible. How is the IsEof function supposed to know that the next item you intend to read is an int?

Should the following also not trigger any asserts?

 while(!IsEof(in))
 {
    int x;
    double y;
    if( rand() % 2 == 0 )
    {
       assert(in >> x);
    } else {
       assert(in >> y);
    }
 }

That said, you can use the exceptions method to keep the "house-keeping' in one place.

Instead of

   if(IsEof(is)) Input(is)

try

   is.exceptions( ifstream::eofbit /* | ifstream::failbit etc. if you like */ )
   try {
     Input(is);
   } catch(const ifstream::failure& ) {
   }

It doesn't stop you from reading before it's "too late", but it does obviate the need to have if(is >> x) if(is >> y) etc. in all the functions.

千里故人稀 2024-11-10 06:15:41

一般情况下,

if (std::is)
{ 
}

就足够了。还有 .good()、.bad()、.fail() 以获得更准确的信息

这是参考链接: http://www.cplusplus.com/reference/iostream/istream/

Normally,

if (std::is)
{ 
}

is enough. There is also .good(), .bad(), .fail() for more exact information

Here is a reference link: http://www.cplusplus.com/reference/iostream/istream/

花心好男孩 2024-11-10 06:15:41

没有 isEof 函数是有充分理由的:很难以可用的方式指定。例如,运算符>>通常首先跳过空格(取决于标志),而其他一些输入函数可以读取空格。 isEof() 如何处理这种情况?是否从跳过空格开始?它是否取决于运算符使用的标志>>或不?它会恢复流中的空白吗?

我的建议是使用标准习惯用法并描述输入失败的特征,而不是尝试仅预测其原因之一:您仍然需要描述和处理其他原因。

There are good reasons for which there is no isEof function: it is hard to specify in an usable way. For instance, operator>> usually begin by skipping white spaces (depending on a flag) while some other input functions are able to read space. How would you isEof() handle the situation? Begin by skipping spaces or not? Would it depend on the flag used by operator>> or not? Would it restore the white spaces in the stream or not?

My advice is use the standard idiom and characterize input failure instead of trying to predict only one cause of them: you'd still need to characterize and handle the others.

羞稚 2024-11-10 06:15:41

不,一般情况下无法知道下一次读操作是否会到达 eof。

如果流连接到键盘,则 EOF 条件是我将在下一个提示时键入 Ctrl+Z/Ctrl+D。 IsEof(is) 如何检测到这一点?

No, in the general case there is no way of knowing if the next read operation will reach eof.

If the stream is connected to a keyboard, the EOF condition is that I will type Ctrl+Z/Ctrl+D at the next prompt. How would IsEof(is) detect that?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文