feof()判断文件结束的问题
我在編寫學(xué)生成績(jī)管理系統(tǒng)時(shí)用到了寫文件和讀文件,發(fā)現(xiàn)讀文件總會(huì)顯示出亂碼,調(diào)試發(fā)現(xiàn)是因?yàn)橛胒eof()做判斷,在讀文件最后時(shí)fread()多讀取了一次。我一開始的解決辦法是每次讀取完文件,都把最后一個(gè)節(jié)點(diǎn)(每一行數(shù)據(jù)都讀取放到鏈表的節(jié)點(diǎn)里)free掉。但這種方法明顯不是那么好。
feof(fp)用來測(cè)試fp所指向的文件當(dāng)前狀態(tài)是否為“文件結(jié)束”。如果文件結(jié)束,則返回1,否則返回0。適合于二進(jìn)制文件和文本文件。
但是,在實(shí)際使用feof時(shí)卻發(fā)生了問題:文件實(shí)際已經(jīng)結(jié)束時(shí)feof還要再判斷一次才返回1
測(cè)試代碼如下:
1 #include <stdio.h>
2 int main()
3 {
4 char ch = 0;
5 int i = 0;
6 FILE* fp;
7 // 建立空文件
8 fp = fopen("Info.txt", "w");
9 if(NULL == fp)
10 {
11 printf("Cannot open file!\n");
12 return 0;
13 }
14 fclose(fp);
15 // 讀取空文件
16 fp = fopen("Info.txt", "r");
17 if(NULL == fp)
18 {
19 printf("Cannot open file!\n");
20 return 0;
21 }
22 while(!feof(fp))
23 {
24 ch = fgetc(fp);
25 i++;
26 }
27 fclose(fp);
28 printf("fread times: %d\n"
29 "note: %c\n", i, ch);
30 return 0;
31 }
得到i為1,ch為空,說明feof()確實(shí)在文件為空狀態(tài)時(shí)判斷有誤。
上網(wǎng)搜索有人說先讀再判斷就不會(huì)有問題了,但試了一下還是不行。對(duì)此,C FAQ-12.3的解釋是“在C語(yǔ)言中,只有輸入例程試圖讀并失敗以后才能得到文件結(jié)束符。...fgets()在遇到文件結(jié)束符的時(shí)候返回NULL。實(shí)際上,在任何情況下,都完全沒必要使用feof()。”
把while(!feof(fp)){}換成while(!fgets(str, 0, fp)){}確實(shí)能保證判斷正確。但是,如果我在函數(shù)體里面還有其他讀操作如fread()的話則會(huì)出現(xiàn)影響。所以,最好的解決辦法是利用fseek()和ftell()配合來判斷文件指針位置:
1 fseek(fp, 0L, SEEK_END);//文件指針置于結(jié)尾
2 len1 = ftell(fp);//獲取結(jié)尾指針值
3 fseek(fp, 0L, SEEK_SET);//文件指針至于開頭
4 len2 = ftell(fp);//獲取開頭指針值
5 while(len2 != len1)//循環(huán)判斷
6 {
7 //do something
8 len2 = ftell(fp);
9 }
結(jié)果正確,無(wú)副作用。
其實(shí)還有另一種解決辦法,就是每次寫文件時(shí)在開頭寫入節(jié)點(diǎn)數(shù),這樣下次讀文件時(shí)就知道要讀取多少數(shù)據(jù)了。
ChinaUnix上也有一篇帖子對(duì)于這個(gè)問題討論得很詳細(xì),但是提供的方法不適合我當(dāng)時(shí)的情況:http://bbs.chinaunix.net/thread-957347-1-1.html
總結(jié)
以上是生活随笔為你收集整理的feof()判断文件结束的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Customizing Download
- 下一篇: BCP 数据的导入和导出