2017-01-26 41 views
2

Apple developer documentation狀態:fgets的n參數的含義是否隨時間而改變?

fgets安全注意:雖然fgets功能提供了讀取數據的數量有限的能力,就必須使用時要小心。像「更安全」列中的其他功能一樣,fgets始終終止字符串。但是,與該列中的其他函數不同,它需要讀取的最大字節數,而不是緩衝區大小。

最後一句對我來說聽起來不對。爲了比較,這裏是what POSIX says

fgets()功能必須從閱讀流字節到陣列指向s直到n-1字節被讀入,或<newline>被讀出並傳送到s,或最終OF-文件條件遇到。在讀入數組的最後一個字節之後立即寫入空字節。

這裏是an ISO C draft from 2005 says

fgets函數讀取比n從流中指定的字符數少至多一個指向stream到陣列通過s指向。換行符(保留)或文件結束後不會讀取其他字符。在讀入數組的最後一個字符後立即寫入空字符。

FreeBSD的手冊頁說一樣的C標準和POSIX。

這讓我覺得蘋果文檔顯然是錯誤的。最簡單的解釋是,蘋果公司在發表這篇文章時並不知情。但雖然很簡單,但這個假設對我來說並不合理。

蘋果是否有其他原因可能偏離C標準的措辭?

+2

該文件是錯誤的。手冊頁是正確的。 – user3386109

+0

更準確地說:文檔不對或者'fgets'實現不符合。我猜這是前者。 –

+0

POSIX似乎很清楚:「直到讀取n-1個字節」 –

回答

1

fgets功能最多大小減去文件一個字節讀取。如果將錯誤值作爲緩衝區大小傳遞,那麼fgets可能會寫出越界。

因此,您顯示的Apple文檔的引用是正確的,因爲該值與從文件中讀取的字節數更相關。但另一方面,任何正常的代碼在使用fgets時會使用實際的緩衝區大小。如果該號碼是從用戶輸入的,那麼在使用之前應該對其進行驗證。

在另一方面文檔繼續狀態

在實際條款(注桑德德Dycker感謝),這意味着你必須總是傳遞一個大小值比規模少一個爲空終止留下空間的緩衝區。如果你不這樣做,fgets函數將盡職地終止字符串,超過緩衝區的末尾,可能會覆蓋隨後的任何字節數據。

這個是錯誤的。傳遞給fgets的大小參數始終包含字符串終止符。至少根據C標準。

+0

這並不能真正回答我的問題。你的參考不像我在我的問題中給出的兩個規範那樣規範,我認爲它甚至包含錯誤的信息。我的問題是關於_why_ Apple可能發佈了這個錯誤信息。 –

2

即使早期(1970年代早期)版本的fgets()指定n是緩衝區的大小,並且所述緩衝器將與'\0'被終止。

Kernighan和Ritchie在他們的所有書籍和文檔中都正確地反映了這一點。然而,一些介紹性文本的作者(我不會嘗試命名,因爲我敢肯定我會錯過一些,並且所有人都應該同樣尷尬),它記錄了最多可以是n的字符寫入緩衝區,並且尾部'\0'可能在某些情況下被丟棄。

+0

我只知道一個作者會寫這樣的廢話,事實上,他的書中有錯誤。 :)很高興知道他不是唯一一個。 –

相關問題