fgets與gets的區別

2021-06-28 14:16:47 字數 1864 閱讀 7126

首先看看他們各自的定義:

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

fgets:讀取的資料儲存在buf指向的字元陣列中,每次最多讀取bufsize-1個字元(第bufsize個字元賦'\0'),如果檔案中的該行,不足bufsize個字元,則讀完該行就結束。如若該行(包括最後乙個換行符)的字元數超過bufsize-1,則fgets只返回乙個不完整的行,但是,緩衝區總是以null字元結尾,對fgets的下一次呼叫會繼續讀該行

今天遇到的乙個問題就是,他們二者對enter鍵引入的換行符的處理。

練習用udp 寫乙個簡單的聊天程式,當客戶端client傳送 訊息給服務端server時,server會將訊息列印到視窗:

printf("%s --from %s\n",recvbuff,inet_ntoa(sockaddrclnt.sin_addr));
但測試中發現,格式不是想要的如圖:

本應該是:你好--from 127.0.0.1

猜測應該是--之前加了個換行符。之前習慣於用gets,沒出現過這種問題。於是除錯一下,看看收到的字串是怎麼樣的。

發現真的多了乙個ascii為0x0a的字元,正是換行符!!

結論:fgets函式會讀取鍵盤輸入的換行符(enter,我們每擊打一下"enter"鍵,向鍵盤緩衝區發去乙個「回車」(\r),乙個「換行"(\n),在這裡\r被scanf()函式處理掉了),並在換行符後加上'\0'.

gets函式將讀取到的換行符轉換為『\0',以此結束字串。

解決方法:在用fgets讀取後,對接收陣列做下處理:

recvbuff[strlen(recvbuff)-1]='\0';
作用就是將換行符換為『\0.』

還有乙個注意點就是:

gets函式可以無限讀取,不會判斷上限,所以程式設計師應該確保buffer的空間足夠大,以便在執行讀操作時不發生溢位。如果溢位,多出來的字元將被寫入到堆疊中,這就覆蓋了堆疊原先的內容,破壞乙個或多個不相關變數的值。這個事實導致gets函式只適用於玩具程式,為了避免這種情況,我們可以用fgets(stdin) (fgets實際上可以讀取標準輸入(即大多數情況下的鍵盤輸入),具體參閱fgets詞條)來替換gets()。在v7的手冊(2023年)中說明:為了向後相容,gets刪除換行符,gets並不將換行符存入緩衝區。

補充一下,getchar也會將換行符放在鍵盤緩衝區

getchar 由巨集實現:#define getchar() getc(stdin)。getchar有乙個int型的返回值.當程式呼叫getchar時.程式就等著使用者按鍵.使用者輸入的字元被存放在鍵盤緩衝區中.直到使用者按回車為止(回車字元也放在緩衝區中).

fgets與gets的區別

1.fgets函式 功能 用於從檔案中讀取一字串 函式原型 char fgets char buf,int bufsize,file stream 引數 buf 字元型指標,指向用來儲存所得資料的位址。bufsize 整型資料,指明儲存資料的大小。stream 檔案結構體指標,將要讀取的檔案流。返回...

fgets和gets的區別

在程式設計中發現gets 和fgets 一些區別總結一下 1 fgets比 gets 安全,使用 gets 編譯時會警告 為了安全,gets 少用,因為其沒有指定輸入字元的大小,限制輸入緩衝區得大小,如果輸入的字元大於定義的陣列長度,會發生記憶體越界,堆疊溢位。後果非常怕怕 fgets會指定大小,如...

fgets()和gets()的區別

區別如下 1 fgets 函式的第2個引數指明了讀入字元的最大數量。如果該引數的值是n,那麼fgets 將讀入n 1個字元,或者讀到遇到的第乙個換行符為止 2 如果fgets 讀到第乙個換行符,會把它儲存在字串中。這點和gets 不同,gets 會丟棄換行符 3 fgets 函式的第3個引數指明要讀...