为什么std :: fstream设置EOF位的方式? [英] Why does std::fstream set the EOF bit the way it does?

查看:289
本文介绍了为什么std :: fstream设置EOF位的方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了使用fstream :: eof()引起的问题。我从此处阅读了以下行:

I recently ran into a problem caused by using fstream::eof(). I read the following line from here:


如果到达关联的输入文件的结尾,函数eof()返回true,否则返回false。

The function eof() returns true if the end of the associated input file has been reached, false otherwise.

和(错误地)假设这意味着如果我使用fstream :: read()并读取超过文件的末尾,函数eof()会告诉我。所以我做了这样的事情(非常笼统):

and (mistakenly) assumed this meant that if I used fstream::read() and read past the end of the file, the function eof() would tell me. So I did something like this (very generalized):

for(int i = 0; i < max && !file.eof(); i++)
{
     file.read(mything, sizeof(mything));
}

问题出现了,因为稍后在上面链接的页面由于误导性的第一段,我最初没有阅读):

The problem came because of what is explained later on the page linked above (which I failed to read initially, thanks to the misleading first paragraph):


相反,如果发生这种情况,流不会进入EOF状态在最后一个令牌之后的任何空格,但试图读取另一个令牌仍然会失败。因此,EOF标志不能用作在用于读取所有流内容直到EOF的循环中的测试。

Conversely, the stream does not go into EOF state if there happens to be any whitespace after the last token, but trying to read another token will still fail. Therefore, the EOF flag cannot be used as a test in a loop intended to read all stream contents until EOF. Instead, one should check for the fail condition after an attempt to read.

所以我改变了,现在我的循环检查文件。 fail()而不是file.eof(),我理解HOW eof()的工作原理。我的问题是,为什么它这样工作?是否存在这种情况?在我看来,一旦你通过EOF,你已经通过EOF和eof()应该返回true。

So I changed, and now my loop checks against file.fail() rather than file.eof(), and I understand HOW eof() works. My question is, why does it work that way? Are there situations where this is desirable? It seems to me that once you've passed EOF, you've passed EOF and eof() should return true.

UPDATE
感谢您的回复,我想我已经得到了。我执行的唯一操作是read(),我立即检查fail(),所以我想我没关系。

UPDATE Thanks for the responses, I think I've got it. The only operation I'm performing is read(), and I immediately check for fail(), so I think I'm okay. Now, my question is, what would I use eof() for?

推荐答案

现在,我的问题是,它可以检测 EOF ,而不知道文件有多大。它只需要尝试读取,如果读取是短的(但不是一个错误),那么你已经到达文件的结尾。

Because this way it can detect EOF without knowing how large the file is. All it has to do is simply attempt to read and if the read is short (but not an error), then you have reached the end of the file.

read 系统调用的功能,其中文件IO通常最后调用(win32的东西可以调用 ReadFile ,但我相信

This mirrors the functionality of the read system call, which file IO typically ends up calling (win32 stuff may call ReadFile but I believe that the functionality is similar).

读取联机帮助页返回值部分/ p>

From the read manpage "RETURN VALUE" section (emphasis added):


成功后,返回读取的字节数
(零表示
文件的结尾)
,文件位置是这个数字提前的
。如果此数字小于
请求的字节数,则不是
错误;这个
可能会发生,例如因为较少的
字节实际上可用现在
(也许因为我们接近
文件结束,或者因为我们正在阅读
从管道,或从终端),或
,因为read()被
信号中断。出错时,返回-1,并且适当地设置
errno。在这个
情况下,它是未指定是否
文件位置(如果有)更改。

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.

一个很好的方式来写你想要的将是这样:

BTW: a good way to write what you wanted would be like this:

T something;
while(file.read(something, sizeof(something))) {
    // process your 'something'
}

这是因为 file.read (像iostream的很多成员)返回一个对iostream本身的引用。所有这些都有一个操作符重载,以允许测试流状态。类似于从 std :: cin while(std :: cin>> x){...}读取

this works because file.read (like many members of iostream) return a reference to the iostream itself. All of which have an operator overloaded to allow testing the stream state. Similarly to read from std::cin, while(std::cin >> x) { ... } works as well.

EDIT:您应该知道测试与失败可能同样错误。如果上一个操作失败,则从您链接到的页面失败()返回这意味着您需要在测试之前执行读取或其他相关操作

you should know that testing vs. fail can be equally wrong for the same reason. From the page you linked to fail() returns if the previous operation failed. Which means you need to perform a read or other relevant operation before testing it.

这篇关于为什么std :: fstream设置EOF位的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆