#include < fstream>
using namespace std;
int main()
{
char ch = 'x';
ifstream fin("test.txt"); //ios::binary
if (fin.eof())
{
cout<<"file is empty."<<endl;
return 0;
}
while (!fin.eof()) //當沒test文件時此循環是死循環 因爲沒機會設置狀態結尾標誌 eof()始終返回false
{
fin.get(ch); //當沒test文件爲空時 執行一次循環,因爲剛開始eof爲false 然後執行get 發現到結尾了 把狀態設置爲ture循環結束
cout<<ch; //當沒test文件爲abcd時 執行5次循環
}
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."<<endl;
return 0;
}
while (!fin.eof())
{
fin >> str;
cout<<str;
//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的。