【问题标题】:Why is the fgets function deprecated?为什么不推荐使用 fgets 函数?
【发布时间】:2013-04-25 17:57:31
【问题描述】:

来自The GNU C Programming Tutorial

fgets("file get string") 函数类似于gets 功能。此功能已弃用 - 这意味着它已过时 并且强烈建议您不要使用它——因为它是 危险的。这很危险,因为如果输入数据包含 null 性格,你说不出来。除非您知道数据,否则不要使用fgets 不能包含空值。不要用它来读取用户编辑的文件 因为,如果用户插入一个空字符,你应该要么 正确处理它或打印明确的错误消息。始终使用 如果可以,getlinegetdelim 而不是 fgets

我认为fgets 函数在遇到\0\n 时会停止;为什么当fgets 应该正确处理输入时,此手册页会建议空字节是“危险的”?此外,getlinefgets 之间有什么区别,fgets 函数在 C99 或未来的 C 标准中是否真正被弃用

【问题讨论】:

    标签: c file-io gnu c99 buffer-overflow


    【解决方案1】:

    不,fgets 在 C99 或当前标准 C11 中实际上并未被弃用。但是该教程的作者是对的,fgets 在遇到 NUL 时不会停止,并且没有报告其读取此类字符的机制。

    fgets 函数读取的字符数最多比n 指定的字符数少一个 从stream 指向的流到s 指向的数组。在换行符(保留)之后或文件结尾之后不会读取其他字符。

    (第 7.21.7.2 节)

    GNU 的 getdelimgetline 已在 POSIX 2008 中标准化,因此如果您的目标是 POSIX 平台,那么改用它们可能不是一个坏主意。

    编辑我认为在面对 NUL 字符时绝对没有使用fgets 的安全方法,但 R..(请参阅 cmets)指出:

    char buf[256];
    
    memset(buf, '\n', sizeof(buf));  // fgets will never write a newline
    fgets(buf, sizeof(buf), fp);
    

    现在在buf 中查找最后一个非\n 字符。不过,我实际上并不推荐这种杂牌。

    【讨论】:

    • @VilhelmGray:没错,它不会告诉你它确实如此。无法确定您找到的第一个 '\0' 是否是由 fgets 添加的。
    • 空字节不属于 text 文件。 fgets() 设计用于处理文本文件:不建议将fgets() 用于二进制数据文件。
    • @VilhelmGray:stdio 倾向于过于信任用户——它只是不会预料到长行、文本文件中的空字符等。这是从 1970 年代开始的,当时防御性编程还没有。 t 被认为和现在一样重要(没有互联网,没有试图闯入您系统的脚本小子,没有在搞砸文本文件时会向您发送垃圾邮件的新手用户)。
    • @R..: 可能,但是当 I/O 不是瓶颈时,我更喜欢我的代码干净。
    • // fgets will never write a newline 评论不清楚。当然,'\n' 在许多fgets() 调用中被写入缓冲区。你的意思是// fgets will never read after a newline
    【解决方案2】:

    这只是 GNU 宣传。在任何官方意义上,fgets 已被弃用。 gets 但是很危险且已弃用。

    【讨论】:

    • gets 实际上已从 2011 ISO C 标准中删除。 (它在 C99 中并未被正式弃用或废弃。)
    • @KeithThompson:ISO/IEC 9899:1999 TC3 的第 7.26.9 节说“gets 函数已过时,已弃用。”所以我相信gets 在 C99 中已被正式弃用。
    • 该语言是在某个 TC 中添加的,还是在 C99 的原始出版物中添加的?
    • @R..:它是由 TC3 添加的。
    猜你喜欢
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 2016-02-23
    • 2017-11-04
    • 2011-10-22
    • 2011-04-11
    • 2021-10-12
    相关资源
    最近更新 更多