共找到2條詞條名為feof的結果 展開
- 函數名
- 檢測流文件指針是否已到達文件結尾
feof
函數名
feof是C語言標準庫函數,其原型在stdio.h中,其功能是檢測流上的文件結束符,如果文件結束,則返回非0值,否則返回0(即,文件結束:返回非0值,文件未結束,返回0值),文件結束符只能被clearerr()清除。(這裡的檢測流上的文件結束符就相當於音效卡檢測電流信號的一個過程)
檢測流上的文件結束符
The function feof() tests the end-of-file indicator for the stream
pointed to by stream, returning non-zero if it is set.The end-of-file
indicator can only be cleared by the functionclearerr().
如果文件結束,則返回非0值,否則返回0,文件結束符只能被clearerr()清除。
int feof(FILE *stream);
參數
流:FILE結構的指針
注意:feof判斷文件結束是通過讀取函數fread/fscanf等返回錯誤來識別的,故而判斷文件是否結束應該是在讀取函數之後進行判斷。比如,在while循環讀取一個文件時,如果是在讀取函數之前進行判斷,則如果文件最後一行是空白行,可能會造成內存錯誤。
feof(fp)有兩個返回值:如果遇到文件結束,函數feof(fp)的值為非零值,否則為0。
EOF是文本文件結束的標誌。在文本文件中,數據是以字元的ASCⅡ代碼值的形式存放,普通字元的ASCⅡ代碼的範圍是32到127(十進位),EOF的16進位代碼為0xFF(十進位為-1),因此可以用EOF作為文件結束標誌。
當把數據以二進位形式存放到文件中時,就會有-1出現,因此不能採用EOF作為二進位文件的結束標誌。為解決這一個問題,ASCIC提供一個feof函數,用來判斷文件是否結束。feof函數既可用以判斷二進位文件又可用以判斷文本文件。
“C”語言的“feof()”函數和資料庫中“eof()”函數的運作是完全不同的。資料庫中“eof()”函數讀取當前指針的位置,“C”語言的“feof()”函數返回的是最後一次“讀操作的內容”。多年來把“位置和內容”相混,從而造成了對這一概念的似是而非。
那麼,位置和內容到底有何不同呢?舉個簡單的例子,比如有人說“你走到火車的最後一節車廂”這就是位置。而如果說“請你一直向後走,摸到鐵軌結束”這就是內容。也就是說用內容來判斷會“多走一節”。這就是完全依賴於“while(!feof(FP)){...}”進行文件複製時,目標文檔總會比源文檔“多出一些”的原因。
在“C”文件讀取操作時不能完全依賴於“while(!feof(FP)){...}”的判斷。下面代碼是改進后的代碼,該代碼執行后output文件內容和input文件內容一致,與使用“while(!feof(FP)){...}”相比,output文件的結尾符號(EOF)沒有被讀入到input文件中。
//main.c linux 下編譯通過、vc下也行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include #include int main(void) { FILE *in, *out; int ch; if ((in = fopen("./output.txt", "r"))== NULL) //input.txt must exist in current directory. { fprintf(stderr, "Cannot open inputfile\n"); exit(0); } if((out=fopen("./input.txt","w"))==NULL) { fprintf(stderr,"Can not open the file.\n"); exit(0); } while(1) { ch=fgetc(in); if(ch == -1) break; fprintf(stdout,"The ASC of char %c is %d\n ",ch,ch); fputc(ch,out); } fclose(in); fclose(out); return 0; } |
與EOF的區別
在stdio.h中可以看到如下定義:
1 2 3 4 5 6 7 8 9 | #define EOF (-1) #define _IOEOF 0x0010 #define feof(_stream) ((_stream)->_flag & _IOEOF) int c; while(!feof(fp)) { c = fgetc(fp); printf("%X\n", c); } |
會發現多輸出了一個FF,原因就是在讀完最後一個字元后,fp->flag仍然沒有被置為_IOEOF,因而feof()仍然沒有探測到文件結尾。直到再次調用fgetc()執行讀操作,feof()才能探測到文件結尾。這樣就多輸出了一個-1(即FF)。
正確的寫法應該是:
1 2 3 4 5 6 7 | int c; c = fgetc(fp); while(!feof(fp)) { printf("%X\n", c); c = fgetc(fp);//最後一個c的值為-1,但是無妨,因為其他所有的循環操作都要放在此句話上面 } |
feof()可以用EOF代替嗎?不可以。fgetc返回-1時,有兩種情況:讀到文件結尾或是讀取錯誤。因此我們無法確信文件已經結束,因為可能是讀取錯誤!這時我們需要feof()。