C语言中的多选菜单程序使用switch语句和scanf()函数

时间:2015-10-16 12:40:24

标签: c

我正在尝试使用C语言中的switch语句编写带有选择菜单的程序。这是我的代码:

main ()
{
    char option;
    int test;
    start:
    printf ("Enter: ");
    scanf ("%c", &option);
    while (getchar() != '\n');
    switch (option)
        {
            case '1': 
                printf ("Test 1 : ");
                scanf ("%d", &test);
                break;
            case '2':
                printf ("Test 2 : ");
                break;
        }
    if (option != 'q') goto start;
}

该程序旨在重复,直到从键盘输入'q'字符。问题是每当我第一次尝试从键盘输入'1'(执行情况1)时,下次输入'1'或'2'时程序将跳过情况1(或2)然后去直接到下一个循环,但是在下一个循环之后它正常执行情况1(或2)。此外,案例2(没有scanf()函数)everthing工作正常。我还试图从案例1中删除scanf,然后案例1正常执行。以下是一些输出:

Enter: 1
Test 1 : 5
Enter: 1
Enter: 1
Test 1 : 7
Enter: 2
Enter: 2
Test 2 :
Enter: 2
Test 2 :

任何人都可以向我解释我的代码有什么问题并告诉我如何修复它吗?

3 个答案:

答案 0 :(得分:0)

而不是goto使用循环 -

while(option!='q'){
   printf ("Enter: ");
  if(scanf (" %c", &option)==1){       // leave a space before %c and check return of scanf
  //while (getchar() != '\n');
  switch (option)
    {
        case '1': 
            printf ("Test 1 : ");
            scanf ("%d", &test);
            break;
        case '2':
            printf ("Test 2 : ");
            break;
    }
  }
}

答案 1 :(得分:0)

stdin 中的当前字符是下一行的第一个字符时,调用case1下的"(这在scanf ("%d", &test)完成后发生。{{1} ''吃'这个字符(可能需要指定下一行选项类型)并且由于这个事实,在下一个循环迭代中调用while (getchar() != '\n')不再能“看到”该字符(它看到了' “而不是下一个。”

答案 2 :(得分:0)

完成代码:

scanf ("%c", &option);

您键入1\n\n是按 Enter 时生成的换行符。以上scanf消费1,将\n留在标准输入流(stdin)中。接着,

while (getchar() != '\n');

消耗\n并突破循环(因为条件为假)。现在,

scanf ("%d", &test);

您输入<number>\n<number>是您输入的数字)。以上scanf消费<number>\n中留下stdin。执行goto后,执行返回

scanf ("%c", &option);

scanf看到前一次调用\n时剩余的stdin中的scanf,并使用它,因此,不会等待进一步的输入。这就是问题所在。

修复它包括更改

  1. 此:

      scanf ("%d", &test);
    

      scanf ("%d%*c", &test); /* `%*c` scans and discards a character */
    
  2.   scanf ("%c", &option);
    

      scanf (" %c", &option); /* The space discards all whitespace characters, if any, until the first non-whitespace character */
    
  3. 使用fgets扫描一行,sscanf相应地解析数据