为什么fgets函数已被弃用?

Vil*_*ray 8 c file-io gnu c99 buffer-overflow

来自GNU C编程教程:

fgets("文件中获取字符串")功能类似于获取功能.这个函数已被弃用 - 这意味着它已经过时,强烈建议你不要使用它 - 因为它很危险.这很危险,因为如果输入数据包含空字符,则无法分辨.fgets除非您知道数据不能包含null,否则请勿使用.不要使用它来读取用户编辑的文件,因为如果用户插入空字符,您应该正确处理它或打印清晰的错误消息.如果可以,请始终使用 getlinegetdelim代替fgets.

我觉得这个fgets功能在遇到a \0或者时会停止\n; 为什么当fgets应该正确处理输入时,这个手册页建议空字节是"危险的" ?此外,之间有什么区别getlinefgets,是fgets真正视为功能过时C99或将来的C标准?

Fre*_*Foo 14

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

fgets函数最多读取一个小于n 指向的数据流指定的字符数所指向stream的数组s.在换行符(保留)或文件结束后不会读取其他字符.

(§7.21.7.2)

GNU的getdelimgetline已经标准化在2008年POSIX,因此,如果您定位的是POSIX平台,那么它可能不是一个坏主意,用这些代替.

编辑我认为fgets面对NUL角色绝对没有安全的方法,但R ..(见评论)指出:

char buf[256];

memset(buf, '\n', sizeof(buf));  // fgets will never write a newline
fgets(buf, sizeof(buf), fp);
Run Code Online (Sandbox Code Playgroud)

现在寻找最后一个非\n字符buf.不过,我实际上不会推荐这种kludge.

  • null字节不属于**text**文件.`fgets()`用于处理文本文件:不推荐使用`fgets()`和二进制数据文件. (5认同)
  • @VilhelmGray:是的,它不会告诉你它确实如此。无法确定您找到的第一个“\0”是否是由“fgets”添加的。 (2认同)
  • @VilhelmGray:`stdio`倾向于过多地信任用户 - 它只是没有预期长行,文本文件中的空字符等等.这是从20世纪70年代开始,当时防御性编程不像现在那样重要(没有互联网,没有脚本小子试图侵入你的系统,没有noob用户,当他们搞砸了一个文本文件时会发送垃圾邮件). (2认同)
  • fgets永远不会写换行符尚不清楚。当然,在许多`fgets()`调用中会将'\ n'写到缓冲区。您是说`// fgets在换行符之后将永远不会读取吗? (2认同)

R..*_*R.. 8

这只是GNU的宣传.在任何官方意义上都不予fgets批准.gets但是很危险并且已弃用.

  • `gets`实际上是*从2011 ISO C标准中删除*.(它在C99中没有被正式弃用或过时.) (5认同)
  • @KeithThompson:ISO/IEC 9899:1999的第7.26.9节TC3说"`gets`函数已经过时,不推荐使用." 所以我相信`gets`在C99中被正式弃用. (3认同)
  • @R ..:由TC3添加. (2认同)