日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

C語言中的EOF和feof()

 心本心123 2021-11-19

原文鏈接:http://blog.csdn.net/flyyyri/article/details/5084981

在c語言中經(jīng)常用EOF和feof()來判斷文件的結(jié)束,現(xiàn)將有關(guān)用法總結(jié)如下:

  1. 定義
    EOF是End Of File 的縮寫,是c語言中標(biāo)準(zhǔn)庫中定義的宏,定義為:#define  EOF  (-1);  
    feof() 用于測試流文件的結(jié)束,有宏和函數(shù)兩種定義:
    宏定義: #define feof(_stream)  ((_stream)->_flag & _IOEOF),其中_IOEOF的為:#define _IOEOF 0x0010
    函數(shù)定義:int feof( FILE *stream );
  2. 說明
          EOF的值為-1,是int類型數(shù)據(jù),在32位系統(tǒng)中,可以表示為0xFFFFFFFF; EOF 不是一個字符,也不是文件中實際存在的內(nèi)容。EOF不但能表示讀文件到了結(jié)尾這一狀態(tài),它還能表示 I/O 操作中的讀、寫錯誤(可以用 ferror() 來檢測)以及其它一些關(guān)聯(lián)操作的錯誤狀態(tài);
          feof()只用于測試流文件的結(jié)束,當(dāng)?shù)竭_(dá)結(jié)尾時,返回非0;當(dāng)文件內(nèi)部位置指針指向文件結(jié)束時,并未立即置位FILE結(jié)構(gòu)中的文件結(jié)束標(biāo)記,只有再執(zhí)行一次讀文件操作,才會置位結(jié)束標(biāo)志,此后調(diào)用feof才會返回為真。
          函數(shù)如fgetc或getc返回EOF并不一定表示文件結(jié)束,當(dāng)讀取文件出錯時也會返回EOF,僅憑返回-1就認(rèn)為文件結(jié)束是錯誤的;正因為如此,我們需要feof()來判斷文件是否結(jié)束,當(dāng)然用feof()來判斷文件結(jié)束時也需要判斷讀取操作是否出錯,這時可以用ferror()來判斷,當(dāng)其為真時表示有錯誤發(fā)生。在實際的程序中,應(yīng)該每執(zhí)行一次文件操作,就用用ferror函數(shù)檢測是否出錯。
  3. 舉例
    假設(shè)文件指針fp指向某個文件,文件中有字符串“hello”,下面的代碼將輸出hello外,還將輸出一個結(jié)束字符EOF(EOF是fgetc函數(shù)的返回值,并不是文件中存在EOF):
    [cpp]  view plain copy
    1. int c=0;  
    2. while(!feof(fp))  
    3. {  
    4.     int c=fgetc(fp);  
    5.     printf('%c:/t%x/n',c,c);  
    6. }  


    其原因就是當(dāng)內(nèi)部指針指向結(jié)尾時,還要執(zhí)行一次讀操作,文件結(jié)束標(biāo)記才置位,而下面的代碼將只輸出“hello”不輸出文件結(jié)束符:
    [cpp]  view plain copy
    1. int c;  
    2.         c=fgetc(fp);      
    3. while(!feof(fp))  
    4. {     
    5.     printf('%c:/t%x/n',c,c);  
    6.     c=fgetc(fp);  
    7. }  


    當(dāng)文件內(nèi)部指針指向結(jié)束位置時,先執(zhí)行一次讀操作,置位文件結(jié)束標(biāo)記,while循環(huán)立即結(jié)束。
  4. 需要注意的幾點

    (1) 字節(jié)的讀取和寫入

          fgetc或getc返回一個int類型數(shù)據(jù),在正常的情況下, fgetc或getc以 unsigned char 的方式讀取文件流, 擴(kuò)張為一個整數(shù),并返回. 換言之, fgetc 從文件流中取一個字節(jié), 并加上24個零,成為一個小于256的整數(shù),然后返回。

    [cpp]  view plain copy
    1. int c;  
    2. while ((c = fgetc (rfp))!= -1) // -1就是 EOF  
    3.     fputc (c, wfp);  
     
          在正常讀取的情況下, 上述fgetc函數(shù)返回的整數(shù)均小于256, 即0x0~0xFF. 而讀不出 0xFFFFFFFF;而寫入時fputc 中的 c 雖然是整數(shù), 但在 fputc 將其寫入文件流之前, 又把整數(shù)的高24位去掉了, 所以如果用fputc把 0xFFFFFFFF 往文件里頭寫, 高24位被屏蔽,寫入的將是 0xFF. 

    (2) fgetc返回值的類型(以(1)中的代碼為例)

           fgetc()返回類型為int,我們可以將其返回值賦給一個int類型變量,如(1)中的代碼,即使是遇到字符0xFF(blank的ascii碼,不是EOF),while循環(huán)也不會結(jié)束,因為0xFF會被轉(zhuǎn)化0x000000FF,顯然這與0xFFFFFFFF(EOF)是不相等的,這時能完成正確復(fù)制;
          如果用一個char 類型的變量c 來接收fgetc()的返回值,會出現(xiàn)什么情況? 假定下一個讀取的字符為0xFF 則:
    char c = fgetc (rfp); // fgetc(rfp)的值為 0x000000FF, 然后強制轉(zhuǎn)化為char類型:c = 0xFF
    while(c != EOF) ;     // 字符與整數(shù)比較? c 被帶符號(signed)擴(kuò)展為0xFFFFFFFF,條件成立,文件復(fù)制提前退出,故遇到空格字符時就退出,不能完成復(fù)制;

          如果將c 定義為unsigned char,當(dāng)讀到文件末尾,返回 EOF 也就是 -1 時:
    unsigned char c = fgetc (rfp);// fgetc (rfp)的值為EOF,即-1,即0xFFFFFFFF,然后強制轉(zhuǎn)化為uchar類型, c=0xFF
    while( c!= -1)  ;                        // c 被擴(kuò)展為 0x000000FF, 永遠(yuǎn)不會等于 0xFFFFFFFF,所以這次雖然能正確復(fù)制 0xFF, 但卻不能判斷文件結(jié)束. 事實上,在 c 為 uchar 時,c != -1 是永遠(yuǎn)成立的!

          因此,只能將c定義成int類型的變量,這樣才與fgetc返回類型一致。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多