1. 程式人生 > >C語言的字串輸入fgets()函式

C語言的字串輸入fgets()函式

C語言的字串輸入fgets()函式



圖片來源-百度圖片

fgets()函式簡介

讀字串函式fgets()的功能是從指定的檔案中讀一個字串到字元陣列中,函式呼叫的形式為: fgets(字元陣列名,n,檔案指標),要從鍵盤輸入時檔案指標的引數為:stdin ; 其中的n是一個正整數。表示從檔案中讀出的字串不超過 n-1個字元。在讀入的最後一個字元後加上串結束標誌'/0'

示例分析

fgets()函式通過2個引數限制讀入的字元數來解決溢位的問題。該函式專門設計用於處理檔案輸入,所以一般情況下可能不太好用。fgets()和gets()的區別如下:

  • fgets()函式的第2個引數指明瞭讀入字元的最大數量。如果該引數的值是n,那麼fgets()將讀入n-1個字元,或者讀到遇到第一個換行符為止。
  • 如果fgets()讀到一個換行符,會把它儲存在字串中。這點與gets()不同,gets()會丟棄換行符。
  • fgets()函式的第三個引數指明要讀入的檔案。如果讀入從鍵盤輸入的資料,則以stdin(標準輸入)作為引數,該標識定義在stdio.h中。

因為fgets()函式把換行符放在字串的末尾(假設輸入行不溢位),通常要與fputs()函式(與puts()類似)配對使用,除非該函式不在字串末尾新增換行符。fgets()函式的第3個引數指明它要寫入的檔案,如果要顯示在計算機顯示器上,應使用stdout(標準輸出)作為該引數。

下面是一個示例:

/*  fgets1.c  -- using fgets() and fputs() */
#include <stdio.h>
#define STLEN 14
int main(void)
{
    char words[STLEN];

    puts("Enter a string, please.");
    fgets(words, STLEN, stdin);
    printf("Your string twice (puts(), then fputs()):\n");
    puts(words);
    fputs(words, stdout);
    puts
("Enter another string, please."); fgets(words, STLEN, stdin); printf("Your string twice (puts(), then fputs()):\n"); puts(words); fputs(words, stdout); puts("Done."); return 0; }

下面是該程式的輸出示例:

Enter a string, please.
apple pie[使用者輸入]
Your string twice (puts(), then fputs()):
apple pie

apple pie
Enter another string, please.
strawberry shortcake[使用者輸入]
Your string twice (puts(), then fputs()):
strawberry sh
strawberry shDone.

第一行輸入,當puts()顯示該字串時又在末尾添加了換行符。因此,apple pie後面有一行空行。因為fputs()不在末尾新增換行符,所以未打印出空行。

第二行輸入,strawberry shortcake,超出了大小的限制。所以fgets()只讀入13個字元,並把strawberry sh\0儲存在陣列中。再次注意,puts()函式會在帶輸出的字串後面新增一個換行符,而fputs()不會這樣做。

如果函式fgets()讀到檔案結尾,它將返回一個空指標(null pointer)。空指標,在程式碼中可以用0代替,不過在C語言中用巨集NULL來代替更常見。

進一步理解

看下面示例:

/*  fgets2.c  -- using fgets() and fputs() */
#include <stdio.h>
#define STLEN 10
int main(void)
{
    char words[STLEN];

    puts("Enter strings (empty line to quit):");
    while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n')
        fputs(words, stdout);
    puts("Done.");

    return 0;
}

下面是該程式的輸出示例:

Enter strings (empty line to quit):
By the way, the gets() function
By the way, the gets() function
also returns a null pointer if it
also returns a null pointer if it
encounters end-of-file.
encounters end-of-file.

Done.

奇怪,該程式似乎在處理過長的輸入時完全沒問題。解釋如下,

程式中的fgets()一次性讀入9個字元。所以一開始它只讀入"By the wa",並存儲為By the wa\0;接著fputs()列印該字串,而且未換行。然後while迴圈進入下一輪迭代,fgets()從剩餘的輸入中讀入資料,即讀入y, the ge並存儲為y, the ge\0;接著fputs()在剛才列印字串這一行接著列印第2次讀入的字串。然後while進入下一輪迭代,fgets()繼續讀取輸入,fgets()列印字串。直到讀到換行符。

系統使用緩衝的I/O。這意味著使用者按下ENTER鍵之前,輸入都被儲存在臨時儲存區(即,緩衝區),按下ENTER鍵就在輸入中增加一個換行符,並把整行輸入發給fgets()。對於輸出,fputs()把字串傳送給另一個緩衝區,當傳送換行符時,緩衝區中的內容被髮送至螢幕。


參考資料:

[1] 史蒂芬・普拉達. C Primer Plus (第6版) 中文版[M]. 人民郵電出版社, 2016.