C語言中文網 目錄

fseek、ftell和rewind函數,C語言fseek、ftell和rewind函數詳解

對于文件的讀寫方式,C 語言不僅支持簡單地順序讀寫方式,還支持隨機讀寫(即只要求讀寫文件中某一指定的部分)。對順序讀寫方式來說,隨機讀寫方式需要將文件內部的位置指針移動到需要讀寫的位置再進行讀寫,這通常也被稱為文件的定位

對于文件的定位,可以通過 rewind、fseek 與 ftell 函數來完成。

其中,rewind 函數用于將文件內部的位置指針重新指向一個流(數據流或者文件)的起始位置。這里需要注意的是,這里的“指針”表示的不是文件指針,而是文件內部的位置指針。即隨著對文件的讀寫,文件的位置指針(指向當前讀寫字節)向后移動。而文件指針指向整個文件,如果不重新賦值,文件指針不會發生改變。

rewind 函數的一般原型如下所示:

void rewind(FILE *fp);

從上面的函數原型可以看出,rewind 并沒有返回值,因此也無法做安全性檢查。如下面的示例代碼所示:
FILE *fp=NULL;
fp=fopen("Test.txt","r");
if(fp==NULL)
{
}
rewind(fp);
在上面的示例代碼中,由于 rewind 函數沒有返回值,所以我們很難判斷“rewind(fp)”是否執行成功。因此,應該盡量使用 fseek 來替換 rewind 函數,從而以驗證流已經成功地回繞。如下面的示例代碼所示:
if (fseek(fp, 0L, SEEK_SET) != 0)
{
}
相對于 rewind 函數而言,fseek 函數的功能更加強大,它用來設定文件的當前讀寫位置,從而可以實現以任意順序訪問文件的不同位置,以實現文件的隨機訪問。其函數的一般原型如下所示:

int fseek(FILE *fp,long offset,int from);

如果該函數執行成功,fp 將指向以 from 為基準,偏移 offset 個字節的位置,函數的返回值為 0;如果該函數執行失敗(比如 offset 超過文件自身大小),則不改變 fp 指向的位置,函數的返回值為 -1,并設置 errno 的值,可以用 perror 函數來輸出錯誤信息。

對于 fseek 函數中的參數:第一個參數 fp 為文件指針;第二個參數 offset 為偏移量,它表示要移動的字節數,整數表示正向偏移,負數表示負向偏移;第三個參數 from 表示設定從文件的哪里開始偏移,取值范圍如表 1 所示。

表 1 from參數取值表
起始點 表不符號 數字表示
文件首 SEEK_SET 0
當前位置 SEEK_CUR 1
文件末尾 SEEK_END 2

由表 1 可知:
  • SEEK_SET 表示從文件起始位置增加 offset 個偏移量為新的讀寫位置;
  • SEEK_CUR 表示從目前的讀寫位置增加 offset 個偏移量為新的讀寫位置;
  • SEEK_END 表示將讀寫位置指向文件尾后,再增加 offset 個偏移量為新的讀寫位置。

當 from 值為 SEEK_CUR 或 SEEK_END 時,參數 offset 允許出現負值。如下面的示例代碼所示:
/*將讀寫位置移動到離文件開頭100字節處*/
fseek(fp,100L,0);
/*將讀寫位置移動到離文件當前位置100字節處*/
fseek(fp,100L,1);
/*將讀寫位置退回到離文件結尾100字節處*/
fseek(fp,-100L,2);
/*將讀寫位置移動到文件的起始位置*/
fseek(fp,0L,SEEK_SET);
/*將讀寫位置移動到文件尾*/
fseek(fp,0L,SEEK_END);
不難發現,上面的語句“(void)fseek(fp,0L,SEEK_SET);”的作用實際上等同于 rewind 函數。與此同時,在使用 fseek 函數時,還應該注意如下 3 點。
  1. 首先,調用 fseek 函數的文件指針 fp 應該指向已經打開的文件,否則將會出現錯誤。
  2. 其次,fseek 函數一般用于二進制文件,當然也可以用于文本文件。需要特別注意的是,當 fseek 函數用于文本文件操作時,一定要注意回車換行的情況。因為在一般瀏覽工具(如 UltraEdit)中,回車換行被視為兩個字符 0x0D 和 0x0A,但真實的文件讀寫和定位卻按照一個字符 0x0A 進行處理。因此,在碰到此類問題時,可以考慮將文件整個讀入內存,然后在內存中手工插入 0x0D的方法,這樣可以達到較好的處理效果。
  3. 最后,fseek 函數只返回執行的結果是否成功,并不返回文件的讀寫位置。因此,你可以使用 ftell 函數來取得當前文件的讀寫位置。

ftell 函數的原型為:

long ftell(FILE *fp);

該函數用于得到文件位置指針當前位置相對于文件首的偏移字節數。在隨機方式存取文件時,由于文件位置頻繁前后移動,程序不容易確定文件的當前位置。在使用 fseek 函數后,再調用函數 ftell 就能非常容易地確定文件的當前位置。如下面的示例代碼所示:
long getfilelength(FILE *fp)
{
    long curpos=0L;
    long length=0L;
    curpos = ftell(fp);
    fseek(fp, 0L, SEEK_END);
    length = ftell(fp);
    fseek(fp, curpos, SEEK_SET);
    return length;
}

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo