关于fstream流中文件结束符的一些问题总结

#include < iostream>   
#include < fstream>   
using namespace std;   
int main()   
{   
char ch = 'x';   
ifstream fin("test.txt"); //ios::binary
if (fin.eof())   
{   
cout<<"file is empty."<
return 0;   
}   
while (!fin.eof())   //当没test文件时此循环是死循环 因为没机会设置状态结尾标志 eof()始终返回false
{   
fin.get(ch);   //当没test文件为空时 执行一次循环,因为刚开始eof为false 然后执行get 发现到结尾了 把状态设置为ture循环结束
cout<
}   
system("pause");   
return 0;   

如果test.txt不存在,程序会形成死循环,fin.eof()永远返回false,就是说,eof在读取完最后一个数据后,仍是False,当再次试图读一个数据时,由于发现没数据可读了 才知道到末尾了,此时才修改标志,eofbit状态改变,之所以是死循环是因为不存在的文件没有机会去设置文件的状态,所以fin.eof()始终返回false

  如果test.txt为空,程序打印出一个x字符,因为循环刚进来时eof()状态还没设置,当读不到数据时设置为ture循环结束;

当test.txt中存在一字符串“abcd”且没有换行时,程序打印出“abcdd”,执行5次循环

当存在以上字符串并且有一新的空行时,程序打印出“abcd”加上一空行。其实是两行 oA输出了两次,显示调试器的caret在第三行,为什么没OD了因为是以文本方式打开的 odoa自动转化为oa;若是以二进制打开的则会读到od

   在这里,大家可能有一个误区,认为eof()返回true时是读到文件的最后一个字符,其实不然,C++ eof()函数返回true时是读到文件结束符0xFF,而文件结束符状态的改变是由于它读到最后一个字符的下一个字符时,它读不到数据就认为文件要结束了,eofbit改变一下,等下次再判断时eof()返回值就变了。

  while (infile.peek()!=EOF)  好处在于(peek()返回当前文件指针下一个位置的字符,而指针位置不会发生改变

注意 peek()是指向文件的开始而不是第一个字符的位置,也就是说它的下一个字符才是第一个字符(刚开始时)

比如上面的abcd char ch=文件.peek(),则ch=a;而不是=b;


#include < iostream>   
#include < fstream>   
#include < string>   
using namespace std;   
int main()   
{   
string str;   
ifstream fin("test.txt"/*, ios::binary*/);   
if (fin.peek() == EOF)   
{   
cout<<"file is empty."< return 0;   
}  
while (!fin.eof())   
{   
fin >> str;   
cout< //str=' ';
}   
system("pause");   
return 0;   

针对用string来读取数据时,道理是一样的 这个程序在test为abcd无回车换行时输出为abcd;

当有换行时输出为abcd

abcd

造成这种情况的原因是string 读数据时是以行为单位并且以回车换行为判断是否一行读完,当abcd无回车换行时,读完后发现找不到0D0A,则认为文件已经结束了,在读完后把eofbit状态改变一下,所以下次循环判断时文件已经结束了,循环只执行一次;

但当abcd+回车换行时,string取得一行并判断结尾是0D0A则认为一行结束,但还没到文件结尾eofbit位不改变,继续下一次循环,下一次循环执行时发现没数据可读了改变eofbit位,但此时循环已经进来了,所以string并没有读到数据,而是上次读的数据的保存值。

如果是abcd加上好几个回车换行循环也是只执行两次,string操作符只对连续几个0D0A0D0A0D0A好像只当一个0D0A


把文件打开换位二进制,则一行结束不是判断ODOA了 而是只判断oA,所以读到的数据会多出一个oD的。

你可能感兴趣的:(c++)