什么是C11中的gets()等价?

Sha*_*ash 19 c c11

来自cplusplus.com

最新版本的C标准(2011年)最终将该功能从其规范中删除

该函数在C++中已弃用(截至2011年标准,遵循C99 + TC3).

我只想知道gets()C11标准的替代方案是什么?

Jon*_*oni 14

在C11 gets中被替换为gets_s具有以下声明:

char *gets_s(char *str, rsize_t n);
Run Code Online (Sandbox Code Playgroud)

该功能将最多读取n-1从字符stdin*str.这是为了避免固有的缓冲区溢出漏洞gets.该功能fgets也是一种选择.来自http://en.cppreference.com/w/c/io/gets:

得到()函数不执行边界检查,因此,此功能非常容易受到缓冲区溢出攻击.它不能安全使用(除非程序在限制stdin上可能出现的内容的环境中运行).因此,该功能已在C99标准的第三个更正中弃用,并在C11标准中完全删除.fgets()gets_s()是推荐的替代品.

永远不要使用gets().

鉴于这gets_s是在标准的扩展中定义的,只有可选的实现,您应该使用fgets而不是编写程序.如果你fgetsstdin你的程序中使用也将在早期版本的C中编译.但请记住行为的不同:当gets_s读取n-1字符时它一直读取直到达到新行或文件结尾,丢弃输入.因此,gets_s您总是在读取整行,即使只有一部分可以在输入缓冲区中返回.

  • 应该注意``gets_s`是可选的,如果实现没有定义`__STDC_LIB_EXT1__`则不需要存在,如果确实如此,需要将`__STDC_WANT_LIB_EXT1__`定义为1(如果没有定义它,它是实现定义的)附件K中的功能是否包含在相应的标题中). (6认同)
  • 应该使用`fgets`.`gets_s`是一个可选的接口,仅存在于Windows上,并且仅出于政治原因在标准中提及.几乎MS之外的每个人都发现_s接口被误导和有害.据报道,部分或全部_s接口的标准化行为甚至不同于现有的实现(MS),使得它们的使用更加有害. (6认同)

Lun*_*din 8

其他人已经回答了这个问题.为了完整起见,这是C标准的建议:

ISO9899:2011 K.3.5.4.1/6

推荐做法

fgets函数允许正确编写的程序安全地处理输入行太长而无法存储在结果数组中.通常,这要求fgets的调用者注意结果数组中是否存在换行符.考虑使用fgets(以及基于换行符的任何所需处理)而不是gets_s.

所以你应该尽可能使用fgets.

编辑

gets_s行为指定为:

ISO9899:2011 K.3.5.4.1/4

描述

gets_s函数最多只读取一个小于n指定的字符数,由stdin指向的流指向s指向的数组.在换行符(被丢弃)之后或文件结束之后,不会读取其他字符.丢弃的换行符不计入读取的字符数.在读入数组的最后一个字符后立即写入空字符.

如果遇到文件结束且没有字符读入数组,或者在操作期间发生读取错误,则s [0]设置为空字符,s的其他元素采用未指定的值.

  • 请注意,如果`n-1`字符中既没有换行符也没有EOF,`gets_s()`会报告约束违规; 获得超长线是错误的. (3认同)