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

C++: std::istream check for EOF without reading / consuming tokens / using operator>>

本文关键字:gt 令牌 运算符 读取 istream std 检查 EOF C++      更新时间:2023-10-16

我想测试一个std::istream是否已经到达终点,而不从中读取。

我知道我可以像这样检查EOF:
if (is >> something) 

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

我要做的就是:

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

方法IsEof应保证流不因读取而改变,因此上述行相当于:

Input(is)

关于Input方法中读取的数据。

如果没有通用的解决方案,将字和std::istream,有没有办法做到这一点,为std::ifstreamcin ?

编辑:

换句话说,下面的assert应该总是通过:

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

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

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

那不可能。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)

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

它不会阻止你在"太晚"之前阅读,但它确实避免了在所有函数中使用if(is>> x) if(is>> y)等。

通常情况下,

if (std::is)
{ 
}

就足够了。还有。good(), .bad(), .fail()来获取更精确的信息

这里有一个参考链接:http://www.cplusplus.com/reference/iostream/istream/

没有isEof函数有很好的理由:它很难以可用的方式指定。例如,操作符>>通常从跳过空白开始(取决于标志),而其他一些输入函数能够读取空白。你会如何处理这种情况?从跳过空格开始还是不开始?它是否依赖于操作符>>使用的标志?它是否会恢复流中的空白?

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

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

如果流连接到键盘,EOF条件是我将在下一个提示符中键入Ctrl+Z/Ctrl+D。我(是)怎么发现的?