使用do..while和if..else语句在C中创建菜单时遇到问题

时间:2016-08-28 06:37:26

标签: c

我是这个编程世界的新手。我在学校学习编程。我的老师最近要求班级创建一个选项有限的菜单,该菜单将以哨兵价值结束。 所以这是我的编码:

#include <stdio.h>

void menu(void);
void choice1();
void choice2();
void choice3();
char choice;

int main() {
    do {
        menu();
        if (choice =='1')
            choice1();
        else if (choice =='2')
            choice2();
        else if (choice =='3')
            choice3();
        else if (choice =='4')
            break;
        else
            printf("Invalid character.");
    } while (choice != '4');
    return 0;
}

void menu(void) {
    printf("\nMenu:\n\n");
    printf("1) Choice 1.\n");
    printf("2) Choice 2.\n");
    printf("3) Choice 3.\n");
    printf("Choose any of the above, or enter 4 to quit.\n\n");
    scanf("%c", &choice);
}

void choice1() {
    printf("\nChoice 1\n");
}

void choice2() {
    printf("\nChoice 2\n");
}

void choice3() {
    printf("\nChoice 3\n");
}

当我尝试运行它时,通过输入数字123,输出结果出来,但之后是函数menu()以及行&#34;字符无效。&#34;出来。至于另一个角色,menu()和&#34;无效的角色&#34;出来两次。号码4确实结束了该计划。我是否有任何改进可以确保menu()和行&#34;无效字符。&#34;没有不必要的出现?

6 个答案:

答案 0 :(得分:4)

在行缓冲输入中,读取单个字符后,换行符会在缓冲区中徘徊,以便选择&#39;因此你会无意中得到Invalid character.

阅读完选择

后,您需要清除缓冲区
scanf("%c", &choice);
while(getchar()!='\n') 
/* Wasting the buffer
 * Hence ensuring that the character you enter
 * is indeed considered for 'choice'
 */
  ;; // Do nothing in particular

作为旁注,您的程序看起来像是switch-case命令的典型用例,也许您的老师希望您使用它。

考虑@chqrlie评论中[ this ]提到的情况,解决方法是在

之后添加
scanf("%c", &choice);

以下行

int c;
while ((c = getchar()) != EOF && c != '\n') 
    ;; //Wasting the buffer

答案 1 :(得分:2)

正如其他答案中已经提到的,问题是换行符。

当您按1然后按Enter键时,您将获得两个字符,即1\n。因此,在处理Invalid character时,您的循环会运行两次并打印\n

以下是您的问题的替代解决方案。只需在%c之前添加一个空格。

scanf(" %c", &choice);

这是有效的,因为该空格将匹配任意数量的空白字符,从而与\n匹配并将其删除。

从手册页:

  

一系列空白字符(空格,制表符,换行符,                 等等.......)。该指令匹配任意数量的                 输入中的空格,包括无空格。

其他评论

您应该始终检查scanf返回的值,以确保您读取正确数量的值。

 if (scanf(" %c", &choice) != 1)
 {
     // Add error handling ....
     // For instance you could terminate the program like
     exit(1);
 } 

在你的程序中choice是一个全局变量。通常,如果可能,应避免使用全局变量。在您的情况下,您可以在choice中将main作为局部变量,并让menu返回char。像:

// char choice;  Remove global variable

int main() {
    char choice; // Add local variable
    do {
        choice = menu();  // Assign to local variable
        .....
}

char menu(void) {    // Make the function return a char
    char choice;     // Add local variable

    printf("\nMenu:\n\n");
    printf("1) Choice 1.\n");
    printf("2) Choice 2.\n");
    printf("3) Choice 3.\n");
    printf("Choose any of the above, or enter 4 to quit.\n\n");
    if (scanf("%c", &choice) != 1) exit(1); // Assign to local variable
                                            // On failure -> exit

    return choice;  // Return value of local variable
}

答案 2 :(得分:2)

问题很简单:终端是行缓冲的:您必须按Enter键才能使输入可用于您的程序,第一个scanf("%c", &choice)检索输入的字符,第二个调用检索换行符({{1由enter键生成的。

有多种方法可以避免此问题。您可以在'\n'格式之前添加空格 scanf%c,或者您可以在第一个字符后读取字符,直到获得scanf(" %c", &choice);

请注意,必须检查'\n'的返回值,以避免在用户输入文件结尾时出现未定义的行为。建议避免使用全局变量:函数scanf应该返回指定的选项。使用menu()语句也更为惯用。

以下是更正后的版本:

switch

答案 3 :(得分:1)

  

当我尝试运行它时,通过输入数字1,2,3,输出来了   然后在功能菜单()和行&#34;无效之后   。字符#&34;出来了。

由于您在每个号码后按下了新的换行符,因此发生了这种情况。它本身就是一个字符,循环再循环一次。因为它是一个无效的角色,这就是为什么&#34;无效的角色。&#34;正在展示。

在scanf()之后尝试使用getchar()

答案 4 :(得分:1)

您可以写scanf(" %c",&choice); (使用空格)而不是scanf("%c",&choice);

答案 5 :(得分:0)

编辑:修复了我之前的while循环,可能会无法退出:

#include <stdio.h>
int main() {
  int choice;
  printf("Menu:\n\n");
  printf("1) Choice 1.\n");
  printf("2) Choice 2.\n");
  printf("2) Choice 3.\n");
  printf("Choose any of the above, or enter 4 to quit.\n\n");
  while (1) {
    char c = scanf("%d",&choice);
    if (c == EOF || choice == 4) break;
    if (choice == 1 || choice == 2 || choice == 3) {
      printf("Choice %d.\n", choice);
    } else {
      printf("Invalid character.\n");
    }
  }
  return 0;
}

如果需要,可以使用功能,但在这种情况下不需要。您需要了解循环实际运行的次数,并将其与您期望的进行比较。

我之前的代码:

#include <stdio.h>
int main() {
  int choice;
  printf("Menu:\n\n");
  printf("1) Choice 1.\n");
  printf("2) Choice 2.\n");
  printf("2) Choice 3.\n");
  printf("Choose any of the above, or enter 4 to quit.\n\n");
  while (scanf("%d", &choice) && choice != 4) {
    if (choice == 1 || choice == 2 || choice == 3) {
      printf("Choice %d.\n", choice);
    } else {
      printf("Invalid character.\n");
    }
  }
  return 0;
}