最近C標準的修訂版(2011)已明確 除去此功能從它的規範
的功能是用C棄用++(如2011標準,該標準如下 C99 + TC3)。
我只是想知道在C11標準中gets()
的替代選擇是什麼?
最近C標準的修訂版(2011)已明確 除去此功能從它的規範
的功能是用C棄用++(如2011標準,該標準如下 C99 + TC3)。
我只是想知道在C11標準中gets()
的替代選擇是什麼?
在C11 gets
已經gets_s
具有以下聲明取代:
char *gets_s(char *str, rsize_t n);
此功能將讀取最多n-1
字符stdin
分成*str
。這是爲了避免gets
固有的緩衝區溢出漏洞。功能fgets
也是一個選項。從http://en.cppreference.com/w/c/io/gets:
的得到()功能不執行邊界檢查,因此,此功能非常容易受到緩衝區溢出攻擊。它不能安全地使用(除非程序運行在限制標準輸入顯示內容的環境中)。出於這個原因,該功能在C99標準的第三勘誤中已被棄用,並在C11標準中完全刪除。 fgets()和gets_s()是推薦的替代品。
千萬不要使用gets()。
鑑於gets_s
是一個可擴展標準定義,只是可選的實施,你應該使用fgets
,而不是寫你的程序。如果在stdin
上使用fgets
,則程序也會在早期版本的C中編譯。但請記住行爲上的差異:當gets_s
已讀取n-1
字符時,它會一直讀取,直到達到新行或文件結束爲止 ,丟棄輸入。因此,對於gets_s
,即使只有一部分可以在輸入緩衝區中返回,您也總是讀取整行。
需要注意的是'gets_s'是可選的,如果實現沒有定義'__STDC_LIB_EXT1__',則不需要存在,如果需要'__STDC_WANT_LIB_EXT1__'定義爲1(如果沒有定義它,定義附件K中的功能是否包含在相應的標題中)。 –
應該使用'fgets'。 'gets_s'是一個可選接口,只存在於Windows上,並且僅出於政治原因在標準中提及。幾乎所有MS以外的人都發現_s接口被誤導和有害。據報道,部分或全部_s接口的標準化行爲甚至不同於現有的唯一實現(即MS),這使得它們的使用更加有害。 –
我懷疑你誤解了gets_s的行爲。就像fgets一樣,它最多可以讀取n-1個字符。不同之處在於,如果遇到新的行字符,gets_s將停止。標準中沒有任何內容表明它在n-1之後繼續閱讀。不要將標準版本與C11之前存在的各種非標準實現相混淆。 – Lundin
其他人已經回答了這個問題。爲了完整起見,這是C標準的推薦:
ISO9899:2011 K.3.5.4。1/6
推薦做法
的與fgets功能允許正確編寫的程序能夠安全地處理輸入線過長的結果 陣列中的存儲。一般來說,這要求fgets的調用者在結果數組中注意存在或不存在換行符。 考慮使用fgets(以及任何基於 換行符的處理)而不是gets_s。
因此,您應該儘可能使用fgets。
EDIT
gets_s行爲被指定爲:
ISO9899:2011 K.3.5.4.1/4
說明
的gets_s函數讀取至多一個少於由stdin指向的流中由n 指定的字符數到s指向的數組中。在換行符(丟棄)或文件結束後,不會讀取其他 字符。 丟棄的換行符不計入讀取的字符數。 A null字符是在讀入數組的最後一個字符後立即寫入的。
如果-的文件端遇到並沒有字符被讀入陣列,或者如果在操作期間發生了讀 錯誤,則s [0]被設置爲空字符,另 元件的s採取未指定的價值。
請注意,如果'n-1'字符中既沒有換行符也沒有EOF,'gets_s()'報告違反約束條件;獲得超長線路是錯誤的。 –
fgets(...,...,stdin) –