2012-10-15 49 views
20

cplusplus.com在C11中获得什么()相当于?

最近C标准的修订版(2011)已明确 除去此功能从它的规范

的功能是用C弃用++(如2011标准,该标准如下 C99 + TC3)。

我只是想知道在C11标准中gets()的替代选择是什么?

+2

fgets(...,...,stdin) –

回答

15

在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,即使只有一部分可以在输入缓冲区中返回,您也总是读取整行。

+6

需要注意的是'gets_s'是可选的,如果实现没有定义'__STDC_LIB_EXT1__',则不需要存在,如果需要'__STDC_WANT_LIB_EXT1__'定义为1(如果没有定义它,定义附件K中的功能是否包含在相应的标题中)。 –

+6

应该使用'fgets'。 'gets_s'是一个可选接口,只存在于Windows上,并且仅出于政治原因在标准中提及。几乎所有MS以外的人都发现_s接口被误导和有害。据报道,部分或全部_s接口的标准化行为甚至不同于现有的唯一实现(即MS),这使得它们的使用更加有害。 –

+0

我怀疑你误解了gets_s的行为。就像fgets一样,它最多可以读取n-1个字符。不同之处在于,如果遇到新的行字符,gets_s将停止。标准中没有任何内容表明它在n-1之后继续阅读。不要将标准版本与C11之前存在的各种非标准实现相混淆。 – Lundin

4

根据man 3 gets,fgets

+0

C11标准中的获取等价物是gets_s,尽管它在技术上应与fgets(...,stdin)相同。 – Lundin

+1

“在出于政治原因而添加的可选附件中”很难“符合C11标准”。您不会在任何地方找到符合C11的_s函数版本,因为没有人计划实施它们。 –

+2

@ R .. C11的附录K是规范性的,即使它不是强制性的。这实际上意味着C实现不能再包含具有与标准冲突的行为的奇怪的非标准gets_s函数。我也敢打赌,GCC将实现这些功能:编译器只是喜欢可选的,冗余的,毫无意义的功能。但是,为了兼容性的原因,我会推荐fgets()。 – Lundin

8

其他人已经回答了这个问题。为了完整起见,这是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采取未指定的价值。

+3

请注意,如果'n-1'字符中既没有换行符也没有EOF,'gets_s()'报告违反约束条件;获得超长线路是错误的。 –

相关问题