我在我的C代码中使用了gets()
函数。虽然代码可以正常运行,但是我收到了一个警告信息。
(.text+0xe6): warning: the `gets' function is dangerous and should not be used.
我希望这个警告信息不要弹出。有没有什么方法?
我在想,通过创建一个头文件来禁用某些警告可能存在这样的可能性。或者在编译期间是否有任何选项可以达到我的目的?或者也许有一种特殊的使用
gets()
的方法可以避免这个警告弹出?我在我的C代码中使用了gets()
函数。虽然代码可以正常运行,但是我收到了一个警告信息。
(.text+0xe6): warning: the `gets' function is dangerous and should not be used.
gets()
的方法可以避免这个警告弹出?#define BUFFER_SIZE 100
char buff[BUFFER_SIZE];
gets( buff); // unsafe!
fgets( buff, sizeof(buff), stdin ); // safe
如果你真的想使用它。
以下是一个回答,引自:http://www.gamedev.net/community/forums/topic.asp?topic_id=523641
如果你使用的是相当新的gcc版本,你可以使用:
#pragma GCC diagnostic ignored "your option here"
例如,如果这些头文件产生“浮点比较是不安全的”错误,您将使用以下代码:#pragma GCC diagnostic ignored "-Wfloat-equal".
不幸的是,你不能通过这种方式禁用 "-Wall"(否则就太简单了吧...),你必须手动选择由-Wall启用的每个警告选项(至少是冲突的选项)。
文档: http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas
编辑: 但对于gets警告似乎不起作用...我在我的电脑上尝试过。
使用fgets()代替gets()
char buffer[BUFSIZ];
/* gets(buffer); */
fgets(buffer,sizeof(buffer), stdin);
gets()函数不会检查缓冲区的长度,可能会写超出缓冲区范围并改变栈的内容。这就是所谓的“缓冲区溢出”。
错误
决不能使用`gets()`。因为在不提前知道数据的情况下,无法确定`gets()`将读取多少个字符,并且因为`gets()`将继续存储超过缓冲区末尾的字符,所以使用它非常危险。它被用来破坏计算机安全。请改用`fgets()`。
没有什么好的理由使用gets()
。即使C标准也说它已经过时了!相反,使用fgets()
。
[编辑]
看起来警告来自链接器。使用-c
进行编译时是否会收到警告?(这将禁用链接。)
你不应该使用gets
函数,man页面建议使用fgets
代替。
GCC不提供使用pragma禁用警告的功能。您必须使用各种警告选项作为编译器的标志。
提供一个安全的gets()
替代方案。
在现有代码中,要替换gets()
,可能不希望使用fgets()
,因为该函数需要一个额外的char
来保存两个函数都使用的'\n'
,但gets()
却没有保存。以下是一种不需要更大缓冲区大小的替代方案。
每个gets(dest)
都替换为:
如果dest
是一个数组,则使用gets_sz(dest, sizeof dest)
如果dest
是指向大小为n
的char
数组的指针,则使用gets_sz(dest, n)
char *gets_sz(char *dest, size_t size) {
if (size <= 1) {
if (size <= 0 || feof(stdin)) {
return NULL;
}
}
size--;
size_t i;
for (i = 0; i < size; i++) {
int ch = getchar();
if (ch == EOF) {
if (i == 0)
return NULL;
break;
}
if (ch == '\n')
break;
dest[i] = (char) ch;
}
dest[i] = 0;
return dest;
}
-fno-stack-protector
是一个选项,它允许使用 gets()
函数,尽管它非常不安全。
-Wno-deprecated-declarations
关闭了过时声明的警告。
以下是使用 gets()
进行编译的示例。
gcc myprogram.c -o myprogram -fno-stack-protector -Wno-deprecated-declarations
我同意所有认为这是完全不安全的人,因为它将允许程序溢出缓冲区。这可能非常危险,因此已被弃用,而推荐使用fgets。
然而,如果你正在学习安全课程,能够编写一个小测试程序来玩弄缓冲区溢出和堆栈溢出的概念非常有帮助。
gets
,即使这样也不起作用了。 - Deebster如果你真的想使用它,请尝试使用标志-fsyntax-only
。
gcc网站上的手册说:
-fsyntax-only
Check the code for syntax errors, but don't do anything beyond that.
与普遍观点相反,不是所有程序员都同样地疏忽他们所写的内容。在 C90 中,gets()
总是标准的,并且出于多个良好的原因被放入库中。如果适当使用,例如在程序示例、文档、单元测试脚手架、家庭作业等方面,它并不比任何其他字符串函数更加"危险"。
更重要的是,gets()
以一种 fgets()
永远不会做到的方式增强了可读性。而且一个人从不必打断思路去查看参数的顺序。
以下解决方法使用我的另一个喜爱函数来移除换行符。
#define gets GET_LOST
#include "stdio.h"
#undef gets
#include "limits.h"
char *gets(char *s)
{
return strtok(fgets(s, INT_MAX, stdin), "\n");
}
'\n'
,则此例程返回 NULL
。原始的 gets()
返回 ""
。 - chux - Reinstate Monica
sizeof buff
来代替复制缓冲区大小。 - Bastien Léonard