【问题标题】:C - menu program using while and switch/case returns duplicate menu with invalid selectionC - 使用 while 和 switch/case 的菜单程序返回无效选择的重复菜单
【发布时间】:2019-09-18 05:15:39
【问题描述】:

头文件:

    #include <stdio.h>
    #include <stdlib.h>

    int print_menu(){
      printf ("MENU\n");
      printf ("1. Total of All Top Scores for the Week\n");
      printf ("2. Total of All High Scores for the Week\n");
      printf ("3. Total Machine High Scores for the Week\n");
      printf ("4. Machine High Score for the Week\n");
      printf ("5. EXIT\n");
      printf ("Enter Selection:");

      int selection = getchar();
      return selection;
    }

主 C 文件:

    #include <stdio.h>
    #include <stdlib.h>
    #include "lab1.h"

    int main(int argc, char *argv[]){
      int selection = print_menu();
      while(1)
      {
        switch (selection)
        {
          case '1':
            printf ("\nselected 1\n");
            break;
          case '2':
            printf ("\nselected 2\n");
            break;
          case '3':
            printf ("\nselected 3\n");
            break;
          case '4':
            printf ("\nselected 4\n");
            break;
          case '5':
            printf ("\nExit\n");
            exit(0);
            break;
          default:
            printf ("Invalid Selection");
            print_menu();
            break;
        };
      };
    }

我的问题是,当我运行程序并输入错误的字符时,程序应该重新打印菜单并再次要求选择。除了它两次打印菜单。示例:

    maiah@maiah-vb:~/shared$ ./a.out
    MENU
    1. Total of All Top Scores for the Week
    2. Total of All High Scores for the Week
    3. Total Machine High Scores for the Week
    4. Machine High Score for the Week
    5. EXIT
    Enter Selection:d
    Invalid Selection
    MENU
    1. Total of All Top Scores for the Week
    2. Total of All High Scores for the Week
    3. Total Machine High Scores for the Week
    4. Machine High Score for the Week
    5. EXIT
    Enter Selection:
    Invalid Selection
    MENU
    1. Total of All Top Scores for the Week
    2. Total of All High Scores for the Week
    3. Total Machine High Scores for the Week
    4. Machine High Score for the Week
    5. EXIT
    Enter Selection:

然后您可以选择输入另一个选项。 当我通过时,我注意到它似乎正在选择“d”并正确输出,但随后自动输入空格或新行并继续检查选择(我不确定这是否是但实际问题 - 这就是它的表现方式)。如果有人对如何解决此问题有任何想法并解释为什么会发生这种情况。任何帮助都会很棒!

【问题讨论】:

  • 不要将代码放在标题中。

标签: c loops while-loop menu switch-statement


【解决方案1】:

您需要保留打印功能返回的内容。

      default:
        printf ("Invalid Selection");
        selection = print_menu();
        break;

第二个问题是您的 getchar() 调用也会在您选择后返回。添加另一个getchar() 以使用它。

int selection = getchar();
(void) getchar(); /* ignore enter key */
return selection;

附带说明,不要将代码放入标头中,仅放入声明中。
否则,代码将在包含标题的每个代码文件(几个)中编译,并为您带来多个定义错误。如果您只有一个包含标头的代码文件,这并不明显,但您应该尽早养成正确的习惯。

最后你需要经常重新读入,不仅仅是在 5 的情况下。

      default:
        printf ("Invalid Selection");
        break;
    };
    selection = print_menu();
}; /* end of while */

即在循环内但在 case 语句之外执行它,因为只有在没有执行其他任何一个时才会采用默认分支。

【讨论】:

  • 我建议使用scanf("%c", &amp;selection); 而不是getchar
  • @vx3r 好的,回答一下优点。
  • @Yunnosch 非常感谢您的解释!我经历并做出了改变。它现在也按照我需要的方式工作,我将打印功能移到 c 文件中!
【解决方案2】:

试试

  while(1)
  {

      int selection = print_menu();
      switch (selection)
      ....
  }

【讨论】:

  • 这有助于解决大多数问题。但请写下您的代码解释,以帮助消除 StackOverflow 是免费代码编写服务的误解,否则只会通过代码这样的回答来传播。此外,“尝试...”给人的印象是“我不确定这是否有帮助。”。我建议尝试更自信的答案。
【解决方案3】:

getchar() 具有从输入缓冲区中删除下一个字符的副作用。

由于scanf() 被告知读取一个且仅一个字符(%c),这具有忽略该输入行上的所有其他内容的效果。

在重新打印菜单之前也要清除控制台。

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>

   int print_menu()
   {
    char selection;

    printf("MENU\n");
    printf("1. Total of All Top Scores for the Week\n");
    printf("2. Total of All High Scores for the Week\n");
    printf("3. Total Machine High Scores for the Week\n");
    printf("4. Machine High Score for the Week\n");
    printf("5. EXIT\n");
    printf("Enter Selection:");

    scanf("%c", &selection);

    return selection;
   }

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

    while(1) {
      selection = print_menu();

      switch (selection)
      {
        case '1':
          printf("\nselected 1\n");
          exit(selection);
          break;
        case '2':
          printf("\nselected 2\n");
          exit(selection);
          break;
        case '3':
          printf("\nselected 3\n");
          exit(selection);
          break;
        case '4':
          printf("\nselected 4\n");
          exit(selection);
          break;
        case '5':
          printf ("\nExit\n");
          exit(0);
          break;
        default:
          system("@cls||clear");
          printf("\nInvalid Selection\n");
          break;
      };
    };
   }

【讨论】:

  • "getchar() 具有从输入缓冲区中删除下一个字符的副作用" 是的,scanf 也是如此。 “scanf() 被告知只读取一个字符 (%c),这会导致忽略该输入行上的所有其他内容”是的,getchar 也会忽略单个字母之外的所有内容。
  • 你测试过这个程序吗?我做到了。无论您输入什么,它都不会循环。如果您删除几个exit(selection),它会循环但总是(除了5)输出“无效选择”。 (我猜想第一个选择sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html中找到
  • 如果您另外删除 system() 调用,您可以看到所需的输出,例如1、紧随其后的是菜单和“无效选择”。请参阅我链接的文章以获得解释,简而言之,scanf() 确实忽略了该行的其余部分,正如您正确指出的那样,它也不会消耗它 - 就像 getch() 一样。
猜你喜欢
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
相关资源
最近更新 更多