c语言 - 程序在 scanf() 之后不执行 gets(),即使使用 fflush(stdin) 也是如此



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

问题在于Fflush(stdin)没有从中做到的事情:程序继续跳过get get get get get get get get get get get get get(),我不能在控制台上写任何短语。

我的代码是下一个:

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

如果Flushing 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;
}

两个大问题:

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

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

使用gets调用遵循scanf呼叫从来都不是一个好主意,因为gets不会跳过scanf输入流中留下的任何领先的新线。使用scanf读取 nombremesaje

printf("Type your name:n");
scanf("%9s", nombre);
printf("Now, type a message:n");
scanf("%79s", mensaje);

scanf%[的CC_11调用中使用明确的长度说明符是一个好主意,否则您会引入与gets相同的安全孔。

编辑

d'OH。我是个白痴。如果您想读取包含空格的字符串,则不能使用%s转换说明符。改用%[转换说明器:

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

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

尝试一下:

scanf("%sn", nombre);

scanf在阅读零件时停在空格上。读取直到第一行。因此,发生的是Scanf在缓冲区中的新线后面的叶子,它立即看到并认为它被赋予了空白。

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

scanf事物中的 n告诉它也继续消费。

尝试gets(stdin);而不是

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

最新更新