即使使用fflush(stdin),程序也不会在scanf()之后执行gets()

时间:2014-03-06 13:51:38

标签: c scanf gets fflush

在使用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;
}

5 个答案:

答案 0 :(得分:6)

如果刷新标准不起作用,请按照建议here尝试阅读额外字符并丢弃。

这将有效:

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

答案 1 :(得分:3)

两大问题:

  1. 请勿在输入流中使用fflush ;未定义fflush对输入流的行为。仅仅因为出现才能在这种情况下工作并不意味着它是正确的。

  2. 永远不会永远不会从不 使用gets - 它已在C99标准中弃用,并已完全从C2011标准中删除。 (不会,)在您的代码中引入一个主要的失败点。

  3. 通过scanf来电跟随gets来电,绝不是一个好主意,因为gets不会跳过输入流中留下的任何前导新行{{1} }。使用scanf阅读 scanfnombre

    mesaje

    printf("Type your name:\n"); scanf("%9s", nombre); printf("Now, type a message:\n"); scanf("%79s", mensaje); scanf的{​​{1}}调用中使用显式长度说明符是个好主意,否则会引入%s所做的相同安全漏洞。

    修改

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

    %s

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

答案 2 :(得分:0)

请改为尝试:

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

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

如果您使用原始代码并输入“名称信息”,两行全部在一行上,您可以看到此操作 - 获取仍将立即返回,但它将看到第二部分。

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

答案 3 :(得分:0)

尝试使用gets(stdin);代替

fflush(stdin);

答案 4 :(得分:-1)

while (fgetc(stdin) != '\n'); // seems to work