看下面一段代码:
ofstream ofs("a.txt");
int n = 1;
while (--n) { //不进入循环体
ofs<<n<<"\t";
}
ofs.close();
int x=5,z = 0;
ifstream ifs("a.txt");
while (!ifs.eof())
{
cout<<ifs.eofbit<<endl; //输出1
x=ifs.get(); -------------》》输出-1,此时ifs指向文件结束符,所以若直接用get()取出,则会出错,出错的表示形式就是输出为-1,所以这个-1表示的是这是一个表示文件结束符,没有其他的数值含义。
// ifs>>x; ----------------》》 输出为5,这种写法与x=ifs.get()不同,在这种形式下,ifs指向文件结束符,所以ifs并没有实际的值,将ifs文件流取到的值赋给x,因为ifs没有值,所以此时x保持不变。
++z;
cout<<x<<"\t"<<flush;
}
ifs.close();
可知此时由于n=1,导致a.txt是空的,但是在从a.txt读时,首先判断ifs是否为EOF,程序这时进入循环,说明不是EOF,并读出此时eofbit为1(true),输出读取的值。然后再从新判断ifs是EOF,退出循环。
--------------》》在文件流中有一个eofbit值,初始化为true,在调用eof()函数进行EOF判断时,就是根据这个eofbit的值来判断的。所以在文件为空时,调用eof(),判断eofbit,此时为true,所以进入循环;此时读取的-1表示文件结束符。在读到这个文件描述符-1之后,文件流类中的eofbit就会置为false(它会辨别是文件里面的数值-1还是文件结束符的-1),再次进入循环判断eof()就会判断EOF,退出循环。----------》》eofbit的值初始化为true,根据读取到的东西判断是否为false,所以在程序进行到读取文件结束符时,eofbit事先不知道这个是文件结束符,只有在读了这个结束符之后才知道已经到文件末尾,并将eofbit置为false。因此,若要判断eof()函数是否为true(即是否到达文件结束),需要先读文件结束符。
再看下面一段代码:
ofstream ofs("a.txt");
int n = 10;
while (--n) {
ofs<<n<<"\t"; //写入9 8 7 6 5 4 3 1
}
ofs.close();
int x=0,z = 0;
ifstream ifs("a.txt");
while (!ifs.eof())
{
ifs>>x;
++z;
cout<<x<<"\t"<<flush; // 输出9 8 7 6 5 4 3 2 1 1
}
ifs.close();
因此,平时在判断文件是否结束使用到eof()函数时,需要注意到是先读文件结束符,eofbit才能置为false,eof()函数才会返回true。所以,在使用时,为了避免错误的情况,可以这样使用:
while
(
true
)
{
ifs>>x;
if
(ifs.eof())
break
;
//先读,读了之后再检测
++z;
cout <<x <<
"\t"
<<flush;
}
如:
while
(ifs.get(ch)!=NULL
)
{
++z;
cout <<ch <<
"\t"
<<flush;
}