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

eol*_*old 5 c++ iostream filestream eof

我想测试一下是否std::istream已达到最终而没有从中读取.

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

if (is >> something) 
Run Code Online (Sandbox Code Playgroud)

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

我需要做的就是:

if (!IsEof(is)) Input(is);
Run Code Online (Sandbox Code Playgroud)

该方法IsEof应保证流不会被更改以进行读取,因此上述行等效于:

Input(is)
Run Code Online (Sandbox Code Playgroud)

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

如果没有可以说明的通用解决方案std::istream,是否有任何方法可以做到这一点std::ifstreamcin

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

while (!IsEof(is)) {
  int something;
  assert(is >> something);
}
Run Code Online (Sandbox Code Playgroud)

小智 8

所述的IStream类具有可以通过使用被检查一个EOF位is.eof()构件.

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

  • 这不能按预期的方式工作,应首先阅读**以使eof()工作.考虑以下代码:while(IsEof(is)){int something; 断言(是>>某事); } (3认同)

Log*_*ldo 5

这不可能。该是怎样IsEof的功能应该知道,你打算读的下一个项目是一个int?

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

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

也就是说,您可以使用该exceptions方法将“房间整理”保留在一个地方。

代替

   if(IsEof(is)) Input(is)
Run Code Online (Sandbox Code Playgroud)

尝试

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

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