在使用C/C++讀文件的時候,一定都使用過C++ eof()函數來判斷文件是否為空或者是否讀到文件結尾了,也會在使用這個函數的過程中遇到一些問題,如不能準確的判斷是否為空或者是否到了文件尾,以至于有些人可能還會懷疑這個函數是不是本身在設計上就有問題。
先來看看如下這段代碼:
#include<iostream>#include<fstream>usingnamespacestd;intmain(){charch='x';ifstreamfin("test.txt"/*,ios::binary*/);if(fin.eof()){cout<<"fileisempty."<<endl;return0;}while(!fin.eof()){fin.get(ch);cout<<ch;}system("pause");return0;}
如果test.txt不存在,程序會形成死循環,fin.eof()永遠返回false,如果test.txt為空,程序打印出一個x字符,當test.txt中存在一字符串“abcd”且沒有換行時,程序打印出“abcdd”,當存在以上字符串并且有一新的空行時,程序打印出“abcd”加上一空行。
這種現象可能讓很多人很迷惑,程序運行的結果似乎很不穩定,時對時錯。使用binary模式讀時結果一樣。在這里,大家可能有一個誤區,認為eof()返回true時是讀到文件的***一個字符,其實不然,C++ eof()函數返回true時是讀到文件結束符0xFF,而文件結束符是***一個字符的下一個字符。
因此,當讀到***一個字符時,程序會多讀一次(編譯器會讓指針停留在***一個字符那里,然后重復讀取一次,這也就是就上面***一個字符會輸出兩次的原因。至于是不是所有的編譯器都這樣處理我就不太清楚了,我使用的VC6,VC8似乎都是這樣的)
問題出來了,就要找出對應的解決之道,要解決以上的問題,只需要調整一下條件語句即可:
fin.peek()==EOF或fin.get(ch)
再來看一下另外一種情況:
#include<iostream>#include<fstream>#include<string>usingnamespacestd;intmain(){stringstr;ifstreamfin("test.txt"/*,ios::binary*/);if(fin.peek()==EOF){cout<<"fileisempty."<<endl;return0;}while(!fin.eof()){fin>>str;cout<<str;}system("pause");return0;}
上述代碼在VC8下編譯運行,發現,當文件結尾沒有空行時,結果正確,當結尾有空行時,***一個字符串將被重復輸出一次, 而VC6的情況則有所不同,沒有重復輸出,但輸出了一個空行。
因此,為了保證在不同的編譯器下得到一致的我們期望的結果,將條件語句做一下修改:
fin>>str
綜上對C++ eof()函數的描述,我們可以得到以下結論:
1. 判斷文件是否為空時使用peek函數,若peek返回EOF則文件為空;
2. 讀取文件過程中,讀取非char型時,使用peek判斷文件尾將不再適用,循環判斷條件應改用>>操作符進行讀取,若讀入char型緩沖區,peek函數會表現得很好。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注本站行業資訊頻道,感謝您對本站的支持。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
(資料圖片)據九派新聞,一項調研發現,英國有數千人不敢去上班,因為他們無力購買基本的衛生用品,會為自己的邋遢形象感到焦慮和羞恥。據英媒《天空新聞》稱,英國民調公司YouGov聯合衛生慈善組織衛生銀行(The Hygiene Bank)開展了這項研究,并在最近公布了報告。報告顯示,在2022年,英國有大約315萬人處于“衛生貧困”(hygiene poverty)狀態,許多人...
開戶名稱是指姓名嗎?開戶名稱的意思是在銀行所開立賬戶的單位名稱或是個人姓名。如果是開立對公賬戶,則開戶名稱即開戶公司所注冊的公司名稱,如果是開立個人賬戶,則開戶名稱應該是個人身份證件上的真實姓名,身份證件包括居民身份證、戶口本、軍人身份證件、護照、港澳通行證等等。銀行賬戶名稱是什么?銀行賬戶分為對公賬戶和個人賬戶。對公賬戶的名稱也就是戶名,是企業工商注冊的名稱。個人賬戶名稱也就是個人賬戶戶名,是本...
文 | 洞見文本|洞察力來源:洞察(ID: DJ 00123987)“不懂是運氣,懂是命?!边@個世界上,有一首歌叫《張開嘴哭》。但是能讓人一開口就哭的歌手不多。如果有的話,他的名字一定是李宗盛。小時候只覺得老李的歌朗朗上口,不好聽。突然有一天,我發現每一句歌詞都鉆進了我的耳朵,我能聽到心碎的聲音。直到這個時候,我才深深體會到那句話:最怕某個年紀突然懂了一首歌;最怕某個年紀突然看一個人?!睹裰{》你我...