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

时间:2010-09-18 01:16:59

标签: c 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位数字,即使我没有在命令窗口中输入字符串,也会打印“输入字符串”行。有谁能解释为什么?有没有办法阻止它发生?

谢谢!

3 个答案:

答案 0 :(得分:4)

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

请注意使用gets 一个坏主意:它无法限制读取缓冲区中的字符数,因此如果输入的字符多于将适合缓冲区,您将最终溢出缓冲区,导致数据损坏,应用程序崩溃,巨大的安全漏洞和/或任何其他不可预测的结果。为了安全起见,您可以使用fgets代替stdin

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

(请注意,您可能希望使用某种符号常量作为string的大小,以便您不会在多个位置重复它 - 或者在数组中使用sizeof(string)定义是可见的。)

答案 1 :(得分:3)

猜测,scanf()没有消耗你必须输入的换行符,这样它就可以处理你想要在字符串之前获得的十个整数。因此,在最后一次调用scanf()之后,gets()面临一个以换行符开头的输入缓冲区。 Presto,它已满足其规范,因此它不会复制到缓冲区并返回。

通常,scanf()gets()是新代码的不良选择。它们都有一些问题会使它们使用起来很痛苦,甚至根本不会使用它们。

具体来说,gets()没有也无法检查其输出缓冲区大小,因此很容易覆盖其缓冲区后发生的任何内存。这种方式是全球国家或堆栈的腐败。如果它是堆栈,则可以利用它来获得对程序的控制并使其执行任意代码。这不是一件好事。

最好使用fgets()来使用输入流,它对缓冲区大小有限制,并在读取后用sscanf()和其他函数解析它。

答案 2 :(得分:0)

以下代码可以使用

#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");
 }

}

char数组[1]用于捕获scanf未经过修改的换行符