最近C标准的修订版(2011)已明确 除去此功能从它的规范
的功能是用C弃用++(如2011标准,该标准如下 C99 + TC3)。
我只是想知道在C11标准中gets()
的替代选择是什么?
最近C标准的修订版(2011)已明确 除去此功能从它的规范
的功能是用C弃用++(如2011标准,该标准如下 C99 + TC3)。
我只是想知道在C11标准中gets()
的替代选择是什么?
在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
,即使只有一部分可以在输入缓冲区中返回,您也总是读取整行。
需要注意的是'gets_s'是可选的,如果实现没有定义'__STDC_LIB_EXT1__',则不需要存在,如果需要'__STDC_WANT_LIB_EXT1__'定义为1(如果没有定义它,定义附件K中的功能是否包含在相应的标题中)。 –
应该使用'fgets'。 'gets_s'是一个可选接口,只存在于Windows上,并且仅出于政治原因在标准中提及。几乎所有MS以外的人都发现_s接口被误导和有害。据报道,部分或全部_s接口的标准化行为甚至不同于现有的唯一实现(即MS),这使得它们的使用更加有害。 –
我怀疑你误解了gets_s的行为。就像fgets一样,它最多可以读取n-1个字符。不同之处在于,如果遇到新的行字符,gets_s将停止。标准中没有任何内容表明它在n-1之后继续阅读。不要将标准版本与C11之前存在的各种非标准实现相混淆。 – Lundin
其他人已经回答了这个问题。为了完整起见,这是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采取未指定的价值。
请注意,如果'n-1'字符中既没有换行符也没有EOF,'gets_s()'报告违反约束条件;获得超长线路是错误的。 –
fgets(...,...,stdin) –