我在C代码中使用函数gets()
。
我的代码工作正常,但我收到一条警告信息
(.text+0xe6): warning: the `gets' function is dangerous and should not be used.
我希望不会弹出此警告消息。有什么办法吗?
我想知道通过创建用于禁用某些警告的头文件可能存在这种可能性。或者在编译期间有任何选项可以满足我的目的吗?或者可能有一种特殊方式使用gets()
来警告这个警告不要弹出?
答案 0 :(得分:27)
显而易见的答案是从编译器试图告诉你的内容中学习 - 你永远不应该使用gets(),因为它完全不安全。请改用fgets(),这样可以防止可能的缓冲区溢出。
#define BUFFER_SIZE 100
char buff[BUFFER_SIZE];
gets( buff); // unsafe!
fgets( buff, sizeof(buff), stdin ); // safe
答案 1 :(得分:24)
如果你真的想要使用它。
以下是答案来自: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”(这太容易了,不会......),你必须做个别警告选项 - 墙上手动启用(至少,冲突)那些)。
文档:http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas
修改强> 但似乎无法获得警告......我在我的电脑上试过了。
答案 2 :(得分:10)
我会注意警告并替换gets
。这对我来说已经足够清楚了:
BUGS
永远不要使用gets()。因为在不知道数据的情况下无法分辨 提前读取多少个字符(),因为gets()将继续存储 超过缓冲区末尾的字符,使用起来非常危险。它有 曾被用来破坏计算机安全。改为使用fgets()。
答案 3 :(得分:8)
使用fgets()代替gets()
char buffer[BUFSIZ];
/* gets(buffer); */
fgets(buffer,sizeof(buffer), stdin);
gets()函数不检查缓冲区的长度,可以写入结束并更改堆栈。这是你听到的“缓冲区溢出”。
答案 4 :(得分:6)
没有充分理由使用gets()
。即使是C标准也说它已经过时了!请改用fgets()
。
[编辑]
看起来警告来自链接器。在使用-c
进行编译时,您会收到警告吗? (这会禁用链接。)
答案 5 :(得分:5)
您根本不应使用gets
功能,该联机帮助页显示使用fgets
代替。
GCC不提供GCC使用编译指示禁用警告的功能。您必须使用各种warning options作为编译器的标志。
答案 6 :(得分:1)
建议安全替代gets()
。
在现有代码中,要替换gets()
,可能不希望使用fgets()
,因为该函数需要额外char
来保存两个函数消耗的'\n'
,但gets()
无法保存。以下是不需要更大缓冲区大小的替代品。
每个gets(dest)
都替换为:
如果dest
是数组,请使用gets_sz(dest, sizeof dest)
如果dest
是指向大小为char
的{{1}}数组的指针,请使用n
gets_sz(dest, n)
答案 7 :(得分:0)
如果您真的想要使用它,请尝试标记-fsyntax-only
。
gcc website中的手册说:
-fsyntax-only
Check the code for syntax errors, but don't do anything beyond that.
答案 8 :(得分:0)
-fno-stack-protector
是一个允许使用gets()
函数的选项,尽管它是多么不安全。
-Wno-deprecated-declarations
关闭过时警告
这是使用gets()
gcc myprogram.c -o myprogram -fno-stack-protector -Wno-deprecated-declarations
我同意每个人的说法,因为这将使程序溢出缓冲区,这是完全不安全的。这可能非常危险,因此不赞成使用fgets的原因。
但是,如果您要学习安全性入门课程,能够编写一个小的测试程序来处理缓冲区溢出和堆栈溢出的概念将非常有帮助。
答案 9 :(得分:-2)
与流行的观点相反,并非所有程序员都对他们所写的内容同样不注意。 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");
}