gets() 接受输入而不实际给它任何输入?
我对 C 相当陌生,很抱歉,如果这是一个愚蠢的问题,但是当我运行以下代码时:
#include <stdio.h>
int main () {
int i;
int test[10];
char string[81];
for(i = 0; i < 10; i++){
scanf("%d", &test[i]);
}
for(i=0; i < 7; i++){
gets(string);
printf("String was entered\n");
}
}
并输入任何 10 位数字,即使我没有在其中输入字符串,也会打印“字符串已输入”行命令窗口。谁能解释为什么?有什么办法阻止它发生吗?
谢谢!
I'm fairly new to C so sorry if this is a stupid question but when I run the following code:
#include <stdio.h>
int main () {
int i;
int test[10];
char string[81];
for(i = 0; i < 10; i++){
scanf("%d", &test[i]);
}
for(i=0; i < 7; i++){
gets(string);
printf("String was entered\n");
}
}
And enter any 10 digits, the line "string was entered" will be printed even though I didn't enter a string in the command window. Can anyone explain why? Is there any way to stop it happening?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用
scanf
读入数据后,换行符仍然位于输入队列中等待读取。gets
读取换行符并停止(因为它已到达行尾!)请注意,使用
gets
是一个坏主意:它提供了无法限制读入缓冲区的字符数,因此,如果您输入的字符多于缓冲区所能容纳的字符数,最终将导致缓冲区溢出,从而导致数据损坏、应用程序崩溃、巨大的损失。安全漏洞和/或任何其他不可预测的结果。作为安全的替代方案,您可以使用fgets
代替stdin
:(请注意,您可能希望使用某种符号常量来表示
string
,这样您就不会在多个地方重复它 - 或者在数组定义可见时使用sizeof(string)
。)After you read in data using
scanf
, the newline is still sitting in the input queue waiting to be read.gets
reads that newline and stops (because it's reached the end of the line!)Note that it's a bad idea to use
gets
: it provides no way to put a limit on how many characters get read into the buffer, so if you type in more characters than will fit in the buffer, you'll end up overflowing the buffer, resulting in data corruption, an application crash, a huge security vulnerability, and/or any number of other unpredictable results. For a safe alternative, you can usefgets
instead withstdin
:(Note that you'd probably want to use a symbolic constant of some kind for the size of
string
so that you don't repeat it in multiple places - or usesizeof(string)
when the array definition is visible.)据猜测,
scanf()
没有消耗您必须键入的换行符,以便它可以处理您想要在字符串之前获取的十个整数。因此,在最后一次调用scanf()
后,gets()
面临着一个以换行符开头的输入缓冲区。很快,它已经满足了它的规范,因此它不会将任何内容复制到其缓冲区并返回。一般来说,对于新代码来说,
scanf()
和gets()
不是很好的选择。它们都存在一些问题,导致正确使用它们很困难,甚至使用起来很危险。具体来说,gets() 不会也无法检查其输出缓冲区大小,因此它很容易覆盖位于其缓冲区之后的任何内存。这样就会导致全局状态或堆栈的损坏。如果是堆栈,则可以利用它来获得程序的控制权并使其执行任意代码。这可不是什么好事。
最好使用
fgets()
使用输入流,该输入流的缓冲区大小有限制,并在读取后使用sscanf()
和其他函数对其进行解析。At a guess,
scanf()
didn't consume the newline that you had to type so that it could process the ten integers you wanted to get before the string. So, after the last call toscanf()
,gets()
is facing an input buffer that begins with a newline. Presto, it has met its spec so it copies nothing to its buffer and returns.In general,
scanf()
andgets()
are poor choices for new code. They both have issues that make them painful to use right, or even dangerous to use at all.Specifically,
gets()
does not and cannot check its output buffer size, so it will readily overwrite whatever memory happens to be located after its buffer. That way lies corruption of global state or the stack. If it is the stack, then it is possible to exploit that to gain control of the program and make it execute arbitrary code. That is not a good thing.It would be better to consume your input stream with
fgets()
which has a limit on its buffer size, and to parse it withsscanf()
and other functions once read.以下代码应有效,
字符数组 s[1] 用于捕获 scanf 未处理的换行符
the following code shall work
the char array s[1] was used to catch the newline character left unproessed by scanf