2010年2月3日 星期三

[C] 使用 fread 讀取檔案的觀念 - 小心使用 End-of-file (EOF)

連續幾天晚睡。主要是想解決一個 bug,這是用 C 語言開發的 tools,但每次都要讀取很多筆資料時才會出現,每一次運作要將三個小時才會看到這個現象,慶幸的,還是追到了。


這個現象碩班時就碰過了,所以知道要處理,然而我碩一下才開始寫 C 語言,恰好是經驗最淺得時候寫了一些 tools ,不曉得還暗藏多少 bug 啊!未來只能繼續見招拆招 。請看看下面的例子:


程式碼


#include <stdio.h>
#include <stdlib.h>

int main()
{
        FILE * fp = stdin;
        char readbuf[4];
        int cnt = 0;
        int length = 0;

        while( !feof( fp ) )
        {
                length = fread( readbuf , 1 , 4 , fp );
                printf( "cnt:%d , data size:%d\n" , ++cnt , length );
        }
        return 0;
}


測資


# echo "123" > data
# ls -la data
rw-r--r-- 1 user group 4 2010-02-03 13:21 data


其中 4 這個數字代表 data 這個檔案的大小,雖然只 echo 三個字元,但它還會幫你多加個換行符號囉


運作結果


# gcc t.c
# ./a.out < data
cnt:1 , data size:4
cnt:2 , data size:0


看得出來嗎?那就是 read buffer size 設成跟讀取資料的大小一樣時,第一次呼叫 fread 時,雖然把資料讀完,但它依舊無法判斷到 end of file 。恰好我的實做上只使用 feof 來判斷有沒讀完資料,接著才要做事,所以就出錯了。因此,最好地作法還是要搭配變數(ex: length)紀錄讀取資料的資訊來加以判斷吧!


1 則留言:

  1. 使用 fstat 先取得檔案大小
    or if (fread (...) == 0)
    break;

    回覆刪除