我用Unix编写C语言,
我正在使用gets
来读取键盘输入。
我总是得到这个警告,程序停止运行:
warning: this program uses gets(), which is unsafe.
有人能告诉我为什么会这样吗?
答案 0 :(得分:14)
gets
是不安全的,因为你给它一个缓冲区,但是你没有告诉它缓冲区有多大。输入可以写入缓冲区的末尾,相当惊人地炸毁你的程序。使用fgets
代替更好一点,因为你告诉它缓冲区有多大,如下所示:
const int bufsize = 4096; /* Or a #define or whatever */
char buffer[bufsize];
fgets(buffer, bufsize, stdin);
...所以如果你给它提供正确的信息,它不会写入缓冲区的末尾并将其搞砸。
稍微加油,但是:
您不必使用const int
作为缓冲区大小,但我强烈建议您不要在两个地方都放一个字面数字,因为你不可避免地要以后会换一个而不是另一个。编译器可以提供帮助:
char buffer[4096];
fgets(buffer, (sizeof buffer / sizeof buffer[0]), stdin);
该表达式在编译时解析,而不是运行时解析。键入是一种痛苦,所以我曾经在我常用的标题集中使用一个宏:
#define ARRAYCOUNT(a) (sizeof a / sizeof a[0])
...但我和我的纯C已经过了几年,这些天可能有更好的方式。
答案 1 :(得分:8)
如前面的答案所述,请使用fgets
代替gets
。
但它不像gets
根本不起作用,它只是非常不安全。我的猜测是,您的代码中存在与fgets
一起显示的错误,因此请发布您的来源。
修改强> 根据您在评论中提供的更新信息,我有一些建议。
我建议用您的母语搜索一个好的C教程,Google就是您的朋友。作为一本书,我建议The C Programming Language
如果您有新信息,最好将它们编辑到原始帖子中,特别是如果它是代码,它会让人们更容易理解您的意思。
您正在尝试将字符串(基本上是一个字符数组)读入单个字符,这当然会失败。你想做的事情如下:
char username[256];
char password[256];
scanf("%s%s", username, password);
随意评论/编辑,即使在基本的C中我也很生疏。
编辑2 正如jamesdlin警告的那样,scanf
的使用与gets
一样危险。
答案 2 :(得分:5)
man gets
说:
永远不要使用gets()。因为它是 在不知道的情况下无法分辨 数据提前有多少个字符 gets()将读取,因为 gets()将继续存储 超过缓冲区末尾的字符, 使用起来非常危险。它 已被用来打破电脑 安全。改为使用fgets()。
答案 3 :(得分:1)
gets()不安全。它需要一个参数,一个指向char缓冲区的指针。问问自己你有多大的缓冲区以及用户输入输入多长时间而无需点击返回键。
基本上,没有办法用gets()来防止缓冲区溢出 - 使用fgets()。