1. 程式人生 > >由GCC中使用gets得到的warning,探究gets、scanf和fgets的用法區別

由GCC中使用gets得到的warning,探究gets、scanf和fgets的用法區別

GCC的編譯檢查出了名的嚴格,在使用gets()時出現warning :

a2.c:6:5: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]

  gets(a);
  ^
/tmp/cceyMQ7u.o: In function `main':

a2.c:(.text+0x41): warning: the `gets' function is dangerous and should not be used.

引起我的注意,遂問之網路,終得到答案。

gets()

gets()從stdin流中讀取字串,直至接受到換行符或EOF時停止,並將讀取的結果存放在buffer指標所指向的字元陣列中。換行符不作為讀取串的內容,讀取的換行符被轉換為null值,並由此來結束字串。

特點:可讀入空格和TAB,但只能以字元型資料讀取,不含回車

注意:gets函式可以無限讀取,不會判斷上限,所以程式設計師應該確保buffer的空間足夠大,以便在執行讀操作時不發生溢位。如果溢位,多出來的字元將被寫入到堆疊中,這就覆蓋了堆疊原先的內容,破壞一個或多個不相關變數的值,為了避免這種情況,我們可以用fgets()來替換gets()(在linux下,程式中用gets(),編譯會有warning:the `gets' function is dangerous and should not beused)。

scanf()

scanf("%s",&s)與gets(s)函式相似,但不完全相同,使用scanf("%s",&s)函式輸入字串時存在一個問題,就是如果輸入了空格、回車或者Tab會認為字串結束,後面的字元將作為下一個輸入項處理,但gets()函式將接收輸入的整個字串直到遇到換行為止。特別注意,輸入回車分隔的多個字串時,回車會放在輸入緩衝區,作為下一次的輸入,所以可以配合getchar()吞掉回車符。

特點:可以指定讀取資料型別,但不能存在空格和TAB,不含回車

注意:和gets一樣

fgets()

fgets函式既可以用來從檔案中讀入字串,也可以從螢幕上輸入一字串。fgets函式的呼叫形式如下:fgets(str,n,fp);此處,fp是檔案指標(此引數寫成stdin即從螢幕取詞);str是存放在字串的起始地址;n是一個int型別變數,表示讀取字串字元的最大數量,函式的功能是從fp所指檔案中讀入n-1個字元放入str為起始地址的空間內;如果在未讀滿n-1個字元之時,已讀到一個換行符或一個EOF(檔案結束標誌),則結束本次讀操作。

特點:讀入的字串中最後包含讀到的換行符(這就是為什麼第二個引數是n,而最多隻能讀入n-1個字元的原因,這個地方一定要注意),如下程式碼:

int len;

char str[128];

fgets(str,128,stdin);

len = strlen(str);

printf("len= %d\n", len);

如果是在標準輸入裡輸入abcd回車

輸出結果是:5而不是4。

所以在需要用到字串長度的時候要特別注意下。因此,確切地說,呼叫fgets函式時,最多隻能讀入n-1個字元。讀入結束後,系統將自動在最後加'\0',並以str作為函式值返回。在題目要求輸入n個字元時,應設定陣列長度至少n+2,尤其注意讀入字元數也是n+2,即包含結尾回車'\n'和結束符'\0'。切記切記。