当我尝试用GCC编译使用gets()函数的C代码时,我得到这个警告:

(.text+0x34):警告:' gets'函数是危险的,不应该使用。

我记得这与堆栈保护和安全性有关,但我不确定确切的原因。

我如何删除这个警告,为什么使用gets()会有这样的警告?

如果gets()是如此危险,那么为什么我们不能删除它?


当前回答

C语言的gets函数是危险的,是一个代价非常高昂的错误。Tony Hoare在他的演讲“Null References: The Billion Dollar Mistake”中特别提到了这一点:

http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare

整个小时都值得一看,但他从30分钟开始的评论观点在39分钟左右受到了批评。

希望这能激发你对整个演讲的兴趣,让你注意到我们如何需要语言中更正式的正确性证明,以及语言设计者如何应该为他们语言中的错误而受到指责,而不是程序员。这似乎是糟糕语言的设计者打着“程序员自由”的幌子把责任推给程序员的全部可疑原因。

其他回答

为了安全地使用get,您必须确切地知道将要读取多少字符,以便使缓冲区足够大。只有当您确切地知道要读取哪些数据时,您才会知道这一点。

您希望使用具有签名的fgets,而不是使用gets

char* fgets(char *string, int length, FILE * stream);

(fgets,如果它读取了整行,将在字符串中留下'\n';你得自己处理。)

直到1999年的ISO C标准,gets仍然是语言的官方部分,但在2011年的标准中被正式删除。大多数C实现仍然支持它,但至少gcc会对任何使用它的代码发出警告。

fgets。

从stdin读取:

char string[512];

fgets(string, sizeof(string), stdin); /* no buffer overflows here, you're safe! */

我想向仍然在库中包含get的C库维护者发出诚挚的邀请,“以防有人仍然依赖它”:请将您的实现替换为

char *gets(char *str)
{
    strcpy(str, "Never use gets!");
    return str;
}

这将有助于确保没有人仍然依赖它。谢谢你!

简单地说,gets() (can)是危险的,因为用户可能会输入比变量有足够空间存储的内容更大的内容。第一个答案是关于fgets()以及为什么它更安全。

在C11(ISO/IEC 9899:201x)中,gets()已被删除。(在ISO/IEC 9899:1999/ co .3:2007(E)中已弃用)

除了fgets(), C11引入了一个新的安全替代gets_s():

C11 K.3.5.4.1 gets_s函数 #定义__STDC_WANT_LIB_EXT1__ # include < stdio . h > (Char *s, rsize_t n);

但是,在推荐实践部分中,fgets()仍然是首选。

fgets函数也允许正确编写的程序安全地处理输入行 在结果数组中存储。一般来说,这要求打电话的人得到报酬 注意结果数组中是否存在换行字符。考虑 使用fget(以及任何基于换行符的必要处理)而不是 gets_s。