有人告诉我,我应该在读取文件时使用while(fin)
而不是使用。while(!fin.eof())
究竟有什么区别?
编辑:我知道while(fin)
实际检查流对象,当它变为 NULL 时,循环中断并且它覆盖 eof 和失败标志。但是我的课程老师说这样fin.eof()
更好,所以我需要了解这里发生的基本操作。
哪一个是正确的做法?
注意:这不是重复的,我需要 Turbo C++ 和二进制文件的帮助。我基本上是在尝试使用类对象读取文件。
有人告诉我,我应该在读取文件时使用while(fin)
而不是使用。while(!fin.eof())
究竟有什么区别?
编辑:我知道while(fin)
实际检查流对象,当它变为 NULL 时,循环中断并且它覆盖 eof 和失败标志。但是我的课程老师说这样fin.eof()
更好,所以我需要了解这里发生的基本操作。
哪一个是正确的做法?
注意:这不是重复的,我需要 Turbo C++ 和二进制文件的帮助。我基本上是在尝试使用类对象读取文件。
首先我假设fin
是你的fstream
对象。在这种情况下,您的老师不会告诉您while(fin.eof())
用于从文件中读取。她会告诉使用while(!fin.eof())
.
让我解释。eof()
是类的成员,它根据您正在读取的文件的文件结尾 (eof) 是否已到达fstream
返回一个true
或值。false
因此 whileeof()
函数返回0
它意味着尚未到达文件末尾并且循环继续执行,但是当eof()
返回1
时已经到达文件末尾并且循环退出。
while(fin)
进入循环是因为fin
实际上返回类对象内的错误标志变量fin
的值,当读取或写入或打开等任何函数失败时,该变量的值设置为 0。因此,只要循环内的读取函数有效,循环就会有效。
就个人而言,我不会建议其中任何一个。我会建议
//假设一个类abc。
abc ob;
While(fin.read((char*)&ob, sizeof(ob)))
{}
或者
While(fin.getline(parameters))
{}
该循环读取循环条件内的文件记录,如果由于到达文件末尾而没有读取任何内容,则退出循环。
问题while(!fin.eof())
在于,1
如果已到达文件末尾,它会返回。文件结尾实际上是放在文件末尾的一个字符。因此,当循环内的 read 函数读取此字符并将变量 eof 设置为 1 时。函数实际上所做的只是返回此值。
因此,当您以文字形式读取行时工作正常,但当您从文件中读取类的连续记录时,此方法将失败。考虑
clas abc
{}a;
Fstream fin("file");
While(!fin.eof())
{
fin.read((char*)&a,sizeof(a));
a.display(); // display is a member function which displays the info }
因此显示最后一条记录两次。这是因为文件结尾字符是最后一条记录的最后一个字节之后的字符。读取最后一个时,文件指针位于 eof 字节但尚未读取它。所以它会再次进入循环,但这次 eof char 被读取但读取函数失败。变量中已有的值a
,即之前的记录将再次显示。
一个快速而简单的解决方法对我有用,可以避免在使用 eof 时出现任何问题,是在第一次阅读后检查它,而不是作为 while 循环本身的条件。像这样的东西:
while (true) // no conditions
{
filein >> string; // an example reading, could be any kind of file reading instruction
if (filein.eof()) break; // break the while loop if eof was reached
// the rest of the code
}
一种好方法是做这样的事情:
while ( instream.read(...) && !instream.eof() ) { //Reading a binary file
Statement1;
Statement2;
}
或者如果是文本文件:
while ( (ch = instream.get()) && !instream.eof() ) { //To read a single character
Statement1;
Statement2;
}
在这里,在 while 循环的条件语句中读取对象,然后测试eof标志的值。这不会导致不希望的输出。
这里我们一起检查实际 I/O 操作的状态和 eof。您还可以检查失败标志。
我想指出,根据@RetiredNinja,我们可能只检查 I/O 操作。那是:
while ( instream.read(...) ) { //Reading a binary file
Statement1;
Statement2;
}