【问题标题】:Menu prints twice and default runs even when case doesn't match即使大小写不匹配,菜单也会打印两次并默认运行
【发布时间】:2022-01-07 20:24:45
【问题描述】:

我正在尝试向用户显示一个菜单并允许他们从选项中进行选择。它在一个while循环中,因为它必须迭代直到选择选项“e”退出程序。如果用户输入不被接受的值,我将“默认”选项作为故障保护。无论我做什么,默认情况总是运行,并且菜单在代码初始运行后总是出现两次。 我尝试将“getchar()”更改为 scanf,它仍然会产生相同的重复输出。我也尝试过完全取消开关,但使用 if/then 语句得到了相同的结果。我已附上我的完整代码,感谢您的帮助!

#include <stdio.h>
#include <stdlib.h>
    // function for the menu
   char menu() {
printf("Please select from the following menu: \n");
// setting up the menu from here
printf("a. input the data files location \n");
printf("b. enter the time interval \n");
printf("c. process and display the US Life Expectancy Data \n");
printf("d. process and display the Statistics of All Data \n");
printf("e. exit the program \n");
    }

    char options(char choice) {
switch (choice) {
case 'a':
    printf("choice a\n");
    break;
case 'b':
    printf("choice b\n");
    break;
case 'c':
    printf("choice c\n");
    break;
case 'd':
    printf("choice d\n");
    break;
case 'e':
    break;
default: // default when none of the cases are matched
    printf("Invalid input\n");
    break;
}
    }

    // main function
    int main(void) {
char choice;
do {
    menu();
    while ((choice = getchar()) == "\n") {};
    if (choice == EOF) {
        exit(1);
    }
    options(choice);
} while (choice != 'e');
    }

【问题讨论】:

  • 欢迎来到 SO。你得到一些编译器警告吗?你应该把它们调到最大。
  • getchar 返回 int,而不是 char。您不应使用全局变量choice。特别是当您将变量传递给option
  • 您没有while 循环,而是do while 循环。调试的一些提示:每当您输入 default 大小写时,打印该值。为此使用%d,而不是%c。您可能会为每个输入找到一个额外的 13
  • 您是否还可以修复应该采用参数的函数 options() 的签名,并激活更高级别的警告(-Wall)
  • 您有不返回任何内容的非 void 函数。和空参数列表但提供参数。我建议重新阅读学习材料中有关函数的章节。

标签: c while-loop switch-statement case


【解决方案1】:

问题是您的代码不处理换行符。换句话说,当您键入a 后按ENTER 时,您的代码实际上会收到两个字符。 'a''\n'。因此菜单会被打印两次,你会得到一个“无效的输入”。

快速解决方法可能是:

choice = getchar(); --> while ((choice = getchar()) == '\n') {};

也就是说,您应该将 choice 更改为 int 并执行以下操作:

int choice;

....
....

    while ((choice = getchar()) == '\n') {};
    if (choice == EOF)
    {
        // Fatal input error
        exit(1);
    }

最后,将choice 作为全局变量是个坏主意。而是将其放入main 并将其作为参数传递给函数options。但不要将其传递给menu。这样做:

char options() { --> char options(int choice) {

int main(void) {
    int choice;
    do {
        menu();
        while ((choice = getchar()) == '\n') {};  // ignore newlines
        if (choice == EOF)
        {
            // Fatal input error
            exit(1);
        }
        options(choice);
    } while (choice != 'e');
}

【讨论】:

  • 这对我了解自己犯了什么错误很有帮助;但是,我仍然遇到与之前菜单打印两次并运行默认情况相同的问题。我将使用更新的代码编辑我的问题。
  • @triniti 请非常仔细地查看您键入的行,并将其与 4386427 键入的 while ((choice = getchar()) == '\n') {}; 行进行比较。 (我也没有发现错误,但我的编译器发现了。)
  • @triniti 您编辑的代码与我的不同。最重要的是你写了"\n" 我写了'\n' 这是一个重要的区别!你也有char choice;,我有int choice;
  • 谢谢!!我的代码现在运行完美,非常感谢您的帮助!!!
猜你喜欢
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
相关资源
最近更新 更多