提问人:roxrook 提问时间:12/26/2010 最后编辑:jwwroxrook 更新时间:6/3/2017 访问量:192157
ifstream 的 eof() 是如何工作的?
How does ifstream's eof() work?
问:
#include <iostream>
#include <fstream>
int main() {
std::fstream inf( "ex.txt", std::ios::in );
while( !inf.eof() ) {
std::cout << inf.get() << "\n";
}
inf.close();
inf.clear();
inf.open( "ex.txt", std::ios::in );
char c;
while( inf >> c ) {
std::cout << c << "\n";
}
return 0;
}
我对功能真的很困惑。假设我的ex.txt的内容是:eof()
abc
它总是读取一个额外的字符,并在阅读时显示。但是给出了正确的输出,即“abc”?谁能帮我解释一下?-1
eof()
inf >> c
答:
EOF 标志仅在读取操作尝试读取文件末尾后设置。 返回符号常量(恰好等于 -1),因为它到达了文件的末尾并且无法读取更多数据,并且只有在那时才为 true。如果要检查此条件,可以执行如下操作:get()
traits::eof()
eof()
int ch;
while ((ch = inf.get()) != EOF) {
std::cout << static_cast<char>(ch) << "\n";
}
评论
int istream::get()
istream::eof()
c
traits::eof()
EOF
char_traits<char>
char_traits<char>::eof()
EOF
get()
traits::eof()
IOSTREAM 不知道它位于文件末尾,直到它尝试读取文件末尾的第一个字符。
cplusplus.com 的示例代码说要这样做:(但你实际上不应该这样做)
while (is.good()) // loop while extraction from file is possible
{
c = is.get(); // get character from file
if (is.good())
cout << c;
}
一个更好的习惯用语是将读取移动到循环条件中,如下所示:
(您可以使用所有返回的读取操作(包括运算符)执行此操作)istream
*this
>>
char c;
while(is.get(c))
cout << c;
评论
istream
<<
>>
!is.fail()
is.good()
is.good()
!is.fail()
eof() 检查流状态下的 eofbit。
在每次读取操作中,如果位置位于流的末尾,并且必须读取更多数据,则 eofbit 设置为 true。因此,在获得 eofbit=1 之前,您将获得一个额外的字符。
正确的方法是在读取操作后检查是否达到了 eof(或者读取操作是否成功)。这就是第二个版本的作用 - 执行读取操作,然后使用生成的流对象引用(>>返回)作为布尔值,这会导致检查 fail()。
评论
-1 表示您已到达文件末尾。使用 (or ) 进行比较 - 避免 -1,这是一个神奇的数字。(虽然另一个有点啰嗦 - 你总是可以打电话get
std::char_traits<char>::eof()
std::istream::traits_type::eof()
istream::eof
)
EOF 标志仅在读取尝试读取文件末尾时设置。如果我有一个 3 字节的文件,而我只读取 3 个字节,则 EOF 是 ,因为我还没有尝试读取文件末尾。虽然这对于通常知道其大小的文件来说似乎令人困惑,但在某些设备(例如管道和网络套接字)上尝试读取之前,EOF 是未知的。false
第二个例子的工作方式是总是返回,其副作用是尝试读取某些内容并将其存储在 中。,在 或 中,将计算文件是否为“良好”:无错误,无 EOF。因此,当读取失败时,会导出到 ,并且循环会正确中止。但是,请遵循以下常见错误:inf >> foo
inf
foo
inf
if
while
true
inf
false
while(!inf.eof()) // EOF is false here
{
inf >> x; // read fails, EOF becomes true, x is not set
// use x // we use x, despite our read failing.
}
但是,这:
while(inf >> x) // Attempt read into x, return false if it fails
{
// will only be entered if read succeeded.
}
这就是我们想要的。
评论
在
输入流 cin
没有字符时查看 () 时会发生什么?标准说它被调用,但当我尝试以这种方式使用它时,peek() 似乎在等待输入。traits::eof()
peek
如果您尝试窥视输入的末尾,将返回 EOF。但是,通常是您键入的终端。(这似乎是你的情况。“等待用户输入”与EOF不同,它只是数据源(您)很慢。所以块,等着你给它输入。如果输入 EOF(在 Linux 上为 Ctrl+D),则将返回,并且应为 true。否则,它将返回您键入的内容。cin
peek
peek
eof
Reaching the End-of-File sets the eofbit. But note that operations that reach the End-of-File may also set the failbit if this makes them fail (thus setting both eofbit and failbit).
评论