我gets()
在我的 C 代码中使用该函数。我的代码工作正常,但我收到一条警告消息
(.text+0xe6): warning: the `gets' function is dangerous and should not be used.
我希望不要弹出此警告消息。有什么办法吗?
我想知道通过创建一个头文件来禁用一些警告可能会有这样的可能性。或者在编译过程中是否有任何选项可以满足我的目的?或者可能有一种特殊的方式使用gets()
这个警告不弹出?
显而易见的答案是从编译器试图告诉你的内容中学习——你永远不应该使用gets(),因为它是完全不安全的。请改用fgets(),这样可以防止可能的缓冲区溢出。
#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
. 这对我来说很清楚:
错误
永远不要使用gets()。因为在事先不知道数据的情况下不可能知道gets()会读取多少个字符,并且因为gets()会继续存储超过缓冲区末尾的字符,所以使用起来非常危险。它已被用来破坏计算机安全。请改用 fgets()。
使用 fgets() 而不是 gets()
char buffer[BUFSIZ];
/* gets(buffer); */
fgets(buffer,sizeof(buffer), stdin);
gets() 函数不检查缓冲区的长度,并且可以写到末尾并更改堆栈。这是您听到的“缓冲区溢出”。
确实没有充分的理由使用gets()
. 甚至 C 标准也说它已经过时了!改为使用fgets()
。
[编辑]
看起来警告来自链接器。编译时是否收到警告-c
?(这会禁用链接。)
您根本不应该使用该gets
功能,手册页说要使用fgets
。
GCC 不提供 GCC 使用编译指示禁用警告的功能。您必须改为使用各种警告选项作为编译器的标志。
建议一个安全的替代品gets()
。
在现有代码中,要替换gets()
,可能不希望使用fgets()
该函数,因为该函数需要额外char
的来保存'\n'
两个函数都使用但gets()
不保存的。以下是不需要更大缓冲区大小的替代品。
每个gets(dest)
都替换为:
Ifdest
是一个数组,使用gets_sz(dest, sizeof dest)
Ifdest
是一个指向char
size 数组的指针n
,使用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。
但是,如果您正在学习安全课程的介绍,那么能够编写一个小型测试程序来处理缓冲区溢出和堆栈溢出的概念是非常有帮助的。
如果您真的想使用它,请尝试 flag -fsyntax-only
。
gcc网站上的手册说:
-fsyntax-only
Check the code for syntax errors, but don't do anything beyond that.
与流行的观点相反,并非所有的程序员都对他们所写的内容同样不专心。 gets()
在 C90 中将始终是标准的,它被放入库中有几个很好的原因。如果使用得当,它并不比任何其他字符串函数更“危险”,例如在程序示例、文档、单元测试脚手架、家庭作业等中。
更重要的是,以前所未有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");
}