複製鏈接
請複製以下鏈接發送給好友

fgets

鎖定
fgets函數功能為從指定的流中讀取數據,每次讀取一行。其原型為:char *fgets(char *str, int n, FILE *stream);從指定的流 stream 讀取一行,並把它存儲在 str 所指向的字符串內。當讀取 (n-1) 個字符時,或者讀取到換行符時,或者到達文件末尾時,它會停止,具體視情況而定。 [1] 
中文名
fgets
外文名
fgets
功    能
讀取數據
函數使用
鍵盤輸入fgets(buf,n,stdin)
長    度
n-1個字符的字符串
頭文件
stdio.h

fgetsfgets函數語法

fgets函數原型

char *fgets(char *str, int n, FILE *stream);

fgets參數

  • str-- 這是指向一個字符數組的指針,該數組存儲了要讀取的字符串。
  • n-- 這是要讀取的最大字符數(包括最後的空字符)。通常是使用以 str 傳遞的數組長度。
  • stream-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要從中讀取字符的流。

fgets功能

從指定的流 stream 讀取一行,並把它存儲在str所指向的字符串內。當讀取(n-1)個字符時,或者讀取到換行符時,或者到達文件末尾時,它會停止,具體視情況而定。 [2] 

fgets應用説明

如果文件中的該行,不足n-1個字符,則讀完該行就結束。如若該行(包括最後一個換行符)的字符數超過n-1,則fgets只返回一個不完整的行,但是,緩衝區總是以NULL字符結尾,對fgets的下一次調用會繼續讀該行。函數成功將返回stream,失敗或讀到文件結尾返回NULL。因此不能直接通過fgets的返回值來判斷函數是否是出錯而終止的,應該藉助feof函數或者ferror函數來判斷。

fgets返回值

如果成功,該函數返回相同的 str 參數。如果到達文件末尾或者沒有讀取到任何字符,str 的內容保持不變,並返回一個空指針。如果發生錯誤,返回一個空指針。
  1. 在讀字符時遇到end-of-file,則eof指示器被設置,如果還沒讀入任何字符就遇到這種情況,則stream保持原來的內容,返回NULL;
  2. 如果發生讀入錯誤,error指示器被設置,返回NULL,stream的值可能被改變。 [3] 

fgets延伸拓展

注意1:《UNIX 環境高級編程》中指出,每次調用fgets函數會造成標準輸出設備自動刷清!案例詳見《UNIX環境高級編程(第二版)》中程序清單1-5和課後習題5.7,習題5.7的答案中給出了相關的論述。
注意2:初入門者,大多數是在WINDOWS下,使用VS進行練習的。此環境下,對注意1中的情況進行測試,並不能看到案例中所描述的情景,因為具體的實現不同。
stream文件流指針體指向文件內容地址的偏移原則
如果使用fgets()讀取某個文件,第一次讀取的bufsize為5,而文件的第一行有10個字符(算上'\n'),那麼讀取文件的指針會偏移至當前讀取完的這個字符之後的位置。也就是第二次再用fgets()讀取文件的時候,則會繼續讀取其後的字符。而,如果使用fgets() 讀取文件的時候bufsize大於該行的字符總數加2(多出來的兩個,一個保存文件本身的'\n'換行,一個保存字符串本身的結束標識'\0'),文件並不會繼續讀下去,僅僅只是這一行讀取完,隨後指向文件的指針會自動偏移至下一行。 [3] 
例:
如果一個文件的當前位置的文本如下
Love, I Have
Since you can do it.
如果用fgets(str1,6,file1);去讀取
則執行後str1 = "Love," ,讀取了6-1=5個字符
這個時候再執行fgets(str1,20,file1)則執行後str1 = " I Have\n"
而如果
fgets(str1,23,file1);
則執行str1="Love ,I Have",讀取了一行(包括行尾的'\n',並自動加上字符串結束符'\0'),當前文件位置移至下一行,雖然23大於當前行上字符總和,可是不會繼續到下一行。而下一次調用fgets()繼續讀取的時候是從下一行開始讀。

fgets示例

#include<string.h>
#include<stdio.h>

int main ( void )
{
    FILE*stream;
    char string[]="Thisisatest";
    char msg[20];
/*openafileforupdate*/
    stream=fopen("DUMMY.FIL","w+");
/*writeastringintothefile*/
    fwrite(string,strlen(string),1,stream);
/*seektothestartofthefile*/
    fseek(stream,0,SEEK_SET);
/*readastringfromthefile*/
    fgets(msg,strlen(string)+1,stream);
/*displaythestring*/
    printf("%s",msg);
    fclose(stream);
    return 0;
}
fgets函數用來從文件中讀入字符串。fgets函數的調用形式如下:fgets(str,n,fp);此處,fp是文件指針;str是存放在字符串的起始地址;n是一個int類型變量。函數的功能是從fp所指文件中讀入n-1個字符放入str為起始地址的空間內;如果在未讀滿n-1個字符之時,已讀到一個換行符或一個EOF(文件結束標誌),則結束本次讀操作,讀入的字符串中最後包含讀到的換行符。因此,確切地説,調用fgets函數時,最多隻能讀入n-1個字符。讀入結束後,系統將自動在最後加'\0',並以str作為函數值返回。

fgets函數使用

同時可以用作鍵盤輸入:fgets(key,n,stdin)且還必須:key[strlen(key)]='\0'或者key[n-1]='\0'
還有種程序經常使用的方法:key[strlen(key-1)]=0x00;
與gets相比使用這個好處是:讀取指定大小的數據,避免gets函數從stdin接收字符串而不檢查它所複製的緩存的容積導致的緩存溢出問題。 [1] 
參考資料
  • 1.    張權.Objective-C函數速查實例手冊 :人民郵電出版社,2014.2
  • 2.    尹德淳.C函數速查手冊 :人民郵電出版社,2009.4
  • 3.    陳超. C語言常用函數速查手冊 : 化學工業出版社 ,2010.6