C - 跳过用户输入?

时间:2016-01-20 13:17:01

标签: c switch-statement printf flush

我想要一个菜单​​,你可以从中选择一些动作。

问题是当我们选择一个时,按下"返回"键,跳过应该是下一步的用户输入命令。那是为什么?

代码是:

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

int main(int argc, char *argv[])
{
    int choice;

    do
    {
     printf("Menu\n\n");
     printf("1. Do this\n");
     printf("2. Do that\n");
     printf("3. Leave\n");
     scanf("%d",&choice);

     switch (choice)
     {
        case 1:
            do_this();
            break;
        case 2:
            // do_that();
            break;
     }

    } while (choice != 3);

    return(0);
}

int do_this()
{
    char name[31];

    printf("Please enter a name (within 30 char) : \n");
    gets(name); // I know using gets is bad but I'm just using it

    // fgets(name,31,stdin); // gives the same problem by the way.

    // Problem is : user input gets skiped to the next statement :
    printf("Something else \n");

    return(0);
}

2 个答案:

答案 0 :(得分:5)

scanf()会留下一个换行符,后续调用gets()会消耗该换行符。

getchar();之后立即使用scanf()或使用循环来阅读和丢弃字符:

int c;
while((c= getchar()) != '\n' && c != EOF); 

我知道你评论gets()是坏人。但即使是玩具程序,你也不应该尝试使用它。它已被从最新的C标准(C11)中删除,即使您正在为C89编程(由于其缓冲区溢出漏洞),也不应该使用它。使用几乎相同的fgets()除了可能留下一个尾随换行符。

如果这是您的完整代码,那么您还需要原型或至少do_this()的声明。隐式int规则也已从C标准中删除。所以添加,

int do_this();

位于源文件的顶部。

答案 1 :(得分:1)

scanf("%d",&choice);

这会将换行符('\n')留在标准输入缓冲区stdin中。

您对gets()的致电仅消耗该空白,不会在name中写入任何内容。

要防止这种情况,请在调用scanf后使用换行符,例如使用getchar()。如果您不在Microsoft平台上,请不要使用fflush(stdin),因为这是未定义的行为(在非MS平台上)。