gets() 接受输入而不实际给它任何输入?

发布于 2024-09-24 13:53:55 字数 422 浏览 1 评论 0原文

我对 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凑诗 2024-10-01 13:53:55

使用 scanf 读入数据后,换行符仍然位于输入队列中等待读取。 gets 读取换行符并停止(因为它已到达行尾!)

请注意,使用 gets 是一个坏主意:它提供了无法限制读入缓冲区的字符数,因此,如果您输入的字符多于缓冲区所能容纳的字符数,最终将导致缓冲区溢出,从而导致数据损坏、应用程序崩溃、巨大的损失。安全漏洞和/或任何其他不可预测的结果。作为安全的替代方案,您可以使用 fgets 代替 stdin:(

fgets(string, sizeof(string), 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 use fgets instead with stdin:

fgets(string, sizeof(string), stdin);

(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 use sizeof(string) when the array definition is visible.)

樱花落人离去 2024-10-01 13:53:55

据猜测,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 to scanf(), 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() and gets() 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 with sscanf() and other functions once read.

屋檐 2024-10-01 13:53:55

以下代码应有效,

#include <stdio.h>
 int main () {
 int i;
  int test[10];
 char string[81],s[1];
 for(i = 0; i < 10; i++){
    scanf("%d", &test[i]);
}

gets(s);

for(i=0; i < 7; i++){
    gets(string);
    printf("String was entered\n");
 }

}

字符数组 s[1] 用于捕获 scanf 未处理的换行符

the following code shall work

#include <stdio.h>
 int main () {
 int i;
  int test[10];
 char string[81],s[1];
 for(i = 0; i < 10; i++){
    scanf("%d", &test[i]);
}

gets(s);

for(i=0; i < 7; i++){
    gets(string);
    printf("String was entered\n");
 }

}

the char array s[1] was used to catch the newline character left unproessed by scanf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文