1

在浪费了太多时间搜索为什么我的程序在使用 scanf() 后不执行 gets() 之后,我找到了一个解决方案,即在 scanf() 之后使用 fflush(stdin) 来启用 gets() 以获取字符串。

问题是 fflush(stdin) 没有达到预期的效果:程序继续跳过gets(),我无法在控制台中写入任何要读取的短语。

我的代码是下一个:

#include <string.h>
#include <stdio.h>

int main(){
    char nombre[10];
    char mensaje[80];

    printf("Type your name:\n");
    scanf("%s", nombre);

    fflush(stdin);

    printf("Now, type a message:\n");
    gets(mensaje);

    printf("3/%s:%s",nombre,mensaje);
    return 0;
}
4

5 回答 5

6

如果刷新 std 不起作用,请尝试按照此处的建议读取多余的字符并丢弃。

这将起作用:

#include <string.h>
#include <stdio.h>

int main(){
    char nombre[10];
    char mensaje[80];
    int c;

    printf("Type your name:\n");
    scanf("%9s", nombre);

    while((c= getchar()) != '\n' && c != EOF)
            /* discard */ ;

    printf("Now, type a message:\n");
    gets(mensaje);

    printf("%s:%s",nombre,mensaje);
    return 0;
}
于 2014-03-06T14:05:54.533 回答
3

两个大的,主要的问题:

  1. 不要fflush在输入流上使用;输入流上的行为fflush未定义。仅仅因为它似乎在这种情况下工作并不意味着它是正确的。

  2. NEVER NEVER NEVER NEVER NEVER NEVER NEVER使用gets- 它在 C99 标准中已被弃用,并已从 C2011 标准中完全删除。它将(不是可能,将)在您的代码引入一个主要的故障点。

scanf在一个呼叫之后跟一个呼叫从来都不是一个好主意gets,因为gets不会跳过输入流中留下的任何前导换行符scanf。用于同时scanf读取和。 nombremesaje

printf("Type your name:\n");
scanf("%9s", nombre);

printf("Now, type a message:\n");
scanf("%79s", mensaje);

scanf调用%sand时使用显式长度说明符是个好主意%[,否则会引入相同的安全漏洞gets

编辑

哦。我是个白痴。如果您尝试读取包含空格的字符串,则不能使用%s转换说明符。请改用%[转换说明符:

scanf( "%79[^\n]", mensage );

这将读取接下来的 79 个字符或换行符,以先到者为准,并将换行符留在输入流中。

于 2014-03-06T16:19:53.453 回答
0

试试这个:

scanf("%s\n", nombre);

scanf 在读取零件时停在空白处。读取直到第一个新行。所以会发生什么是 scanf 在缓冲区中留下一个换行符,它立即看到并认为它被赋予了一个空行。

如果您使用原始代码并输入“名称消息”,两部分都在一行中,您可以看到这一点 - 获取仍然会立即返回,但它会看到第二部分。

scanf 中的 \n 告诉它继续使用它。

于 2014-03-06T13:55:10.767 回答
0

尝试gets(stdin);代替

fflush(stdin);
于 2014-03-06T14:05:21.717 回答
-1
while (fgetc(stdin) != '\n'); // seems to work
于 2018-05-19T15:05:05.663 回答