2012-10-15 51 views
20

cplusplus.com在C11中獲得什麼()相當於?

最近C標準的修訂版(2011)已明確 除去此功能從它的規範

的功能是用C棄用++(如2011標準,該標準如下 C99 + TC3)。

我只是想知道在C11標準中gets()的替代選擇是什麼?

+2

fgets(...,...,stdin) –

回答

15

在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,即使只有一部分可以在輸入緩衝區中返回,您也總是讀取整行。

+6

需要注意的是'gets_s'是可選的,如果實現沒有定義'__STDC_LIB_EXT1__',則不需要存在,如果需要'__STDC_WANT_LIB_EXT1__'定義爲1(如果沒有定義它,定義附件K中的功能是否包含在相應的標題中)。 –

+6

應該使用'fgets'。 'gets_s'是一個可選接口,只存在於Windows上,並且僅出於政治原因在標準中提及。幾乎所有MS以外的人都發現_s接口被誤導和有害。據報道,部分或全部_s接口的標準化行爲甚至不同於現有的唯一實現(即MS),這使得它們的使用更加有害。 –

+0

我懷疑你誤解了gets_s的行爲。就像fgets一樣,它最多可以讀取n-1個字符。不同之處在於,如果遇到新的行字符,gets_s將停止。標準中沒有任何內容表明它在n-1之後繼續閱讀。不要將標準版本與C11之前存在的各種非標準實現相混淆。 – Lundin

4

根據man 3 gets,fgets

+0

C11標準中的獲取等價物是gets_s,儘管它在技術上應與fgets(...,stdin)相同。 – Lundin

+1

「在出於政治原因而添加的可選附件中」很難「符合C11標準」。您不會在任何地方找到符合C11的_s函數版本,因爲沒有人計劃實施它們。 –

+2

@ R .. C11的附錄K是規範性的,即使它不是強制性的。這實際上意味着C實現不能再包含具有與標準衝突的行爲的奇怪的非標準gets_s函數。我也敢打賭,GCC將實現這些功能:編譯器只是喜歡可選的,冗餘的,毫無意義的功能。但是,爲了兼容性的原因,我會推薦fgets()。 – Lundin

8

其他人已經回答了這個問題。爲了完整起見,這是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採取未指定的價值。

+3

請注意,如果'n-1'字符中既沒有換行符也沒有EOF,'gets_s()'報告違反約束條件;獲得超長線路是錯誤的。 –

相關問題