C 为什么这个无效输入仍然有效?(开关箱)字符错误

C 为什么这个无效输入仍然有效?(开关箱)字符错误,c,switch-statement,C,Switch Statement,更新代码 为什么输入12有效?它将12解释为选项1,并将2作为案例“1”的第一次扫描?我不想使用int-opcao,就好像我输入了一个leter,它将不确定地运行一样 我想,用户只能退出程序时,他选择退出选项(其中一种情况),这样做。。。当。如果用户输入无效字符或leter或任何菜单再次显示并显示默认消息时。我还希望在所选的案例执行后,它会再次显示新选项的菜单,因此我同时使用1=1的始终有效条件。我不能像输入一个leter那样使用整数,因为程序会疯掉,也就是说,永远不会停止运行。试试看 char

更新代码

为什么输入12有效?它将12解释为选项1,并将2作为案例“1”的第一次扫描?我不想使用int-opcao,就好像我输入了一个leter,它将不确定地运行一样

我想,用户只能退出程序时,他选择退出选项(其中一种情况),这样做。。。当。如果用户输入无效字符或leter或任何菜单再次显示并显示默认消息时。我还希望在所选的案例执行后,它会再次显示新选项的菜单,因此我同时使用1=1的始终有效条件。我不能像输入一个leter那样使用整数,因为程序会疯掉,也就是说,永远不会停止运行。试试看

char opcao;



do {
    menu();
    scanf(" %c",&opcao);

    switch(opcao) {
      case '1':
    printf("Massa do módulo (sem combustível):\n");
    scanf("%f",&m_modulo);
    printf("Massa de combustível:\n");
    scanf("%f",&m_combustivel);
    printf("Altitude no início da alunagem em relação a um ponto de referência:\n");
    break;
      case '2':

    break;
      case '3':
    printf("Funcionalidade nao disponivel.\n");
    break;
      case '4':
    printf("Funcionalidade nao disponivel.\n");
    break;
      case '5':
    printf("Funcionalidade nao disponivel.\n");
    break;
      case '6':
    exit(0);
    break;
      default:
    printf("Opcao invalida, as seguintes opcoes estao disponiveis:\n");
    break;
    }
  }
while(1==1);

这是因为您正在使用单个
%c
读取输入

这样,12(1)的第一个字符由开关使用,而第二个字符由
案例“1”的scanf使用:

为了避免这种行为,您可以将选项作为整数读取,并在第一次
scanf
中使用占位符
%d


编辑:

要避免infinte循环问题,可以执行以下操作:

#include <stdio.h>

void clean_stdin();

int main() {
  int opcao;
  float m_modulo, m_combustivel;
  int flag = 0;

  do {
      printf("Make a choice: ");
      if (scanf("%d", &opcao) == 0) {
        clean_stdin();
      }
      else {
          switch(opcao) {
            case 1:
                    printf("Massa do módulo (sem combustível): ");
                    scanf("%f", &m_modulo);
                    printf("Massa de combustível: ");
                    scanf("%f", &m_combustivel);
                    printf("Altitude no início da alunagem em relação a um ponto de referência.\n");
                    break;
            case 2:

                    break;
            case 3:
                    printf("Funcionalidade nao disponivel.\n");
                     break;
            case 4:
                    printf("Funcionalidade nao disponivel.\n");
                     break;
            case 5:
                    printf("Funcionalidade nao disponivel.\n");
                    break;
            case 6:
                    flag = 1;
                    break;
            default:
                    printf("Opcao invalida, as seguintes opcoes estao disponiveis:\n");
          }
      }

  } while(flag == 0);
}

void clean_stdin()
{
    int c;
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
}
#包括
无效清洁标准();
int main(){
国际组织;
浮点数m_模,m_自燃;
int标志=0;
做{
printf(“做出选择:”);
如果(scanf(“%d”,&opcao)==0){
清洁卫生标准();
}
否则{
交换机(opcao){
案例1:
printf(“Massa do módulo(sem Combumível):”;
scanf(“%f”&m_模);
printf(“燃烧层”);
scanf(“%f”和m_combustivel);
printf(“参考点附近的海拔高度);
打破
案例2:
打破
案例3:
printf(“functionalidade nao disponivel.\n”);
打破
案例4:
printf(“functionalidade nao disponivel.\n”);
打破
案例5:
printf(“functionalidade nao disponivel.\n”);
打破
案例6:
flag=1;
打破
违约:
printf(“残废军人,因其身份为:;
}
}
}while(flag==0);
}
void clean_stdin()
{
INTC;
做{
c=getchar();
}而(c!='\n'&&c!=EOF);
}
我所做的工作如下:

  • 检查scanf输出是否正确读取输入(在这种特定情况下,如果输入是一个数字,则返回一个不同于0的数字)
  • 使用函数
    clean\u stdin
    ()清除扫描读取但未使用的字符(它需要一个数字,您给它一个字符,因此字符保留在stdin中并创建无限循环)
  • 我使用一个标志来控制循环条件,当选择退出选项时,标志值将更改为使条件失败的值
  • 我添加了
    main()
    ,因为我需要它来运行程序;您可以将其中的内容合并到
    main
    中。记住复制
    clean_stdin()
    函数
我建议你读一些来了解它的返回值

我还建议您阅读一下scanf的替代方案,因为它是一个无聊的函数:and


请记住使用正确的缩进设置代码的格式,这是最佳做法。

这就是
scanf
的工作原理

您要求
scanf
从输入流中读取单个字符。输入流最初包含
12
序列(更有可能是
12
序列)。因此,正如您要求的那样,
scanf
使用了第一个
1
,将其余部分保留在输入流中


下一个
scanf
继续使用前一个停止的输入流。

scanf
使用
%c
可以一次读取一个字符“12”包含两个字符“1”和“2”。因此,
scanf
将首先使用'1',因此,
案例'1':
将被执行。“2”留在输入缓冲区(
stdin
)中,它将被下一个
scanf
使用
%c
消耗

为了避免这种情况,可以将
opcao
声明为整数,并使用以下代码:

    while(1)
     {
              if(scanf("%d",&opcao)==0)
              {
              printf("Invalid input. Try again:");
              scanf("%*s"); //remove the invalid input
              continue;
              }
              if(opcao>0 && opcao<7)
              break;
              else
              printf("invalid integer. Try again:");
     }
    switch(opcao) {
      case 1://your code
    break;
      case 2://your code
    break;
      case 3://your code
    break;
       // etc...
       case 6:exit(0);
             }
  //no need of do...while or a default case
while(1)
{
如果(scanf(“%d”,&opcao)==0)
{
printf(“无效输入。请重试:”;
scanf(“%*s”);//删除无效输入
继续;
}

如果(opcao>0&&opcao使用
opcao=getch()
而不是
scanf(“%c”,&opcao)
while(opcao!=1 | | opcao!=2 | | opcao!=3 | | opcao!=4 | | opcao!=5 | | | opcao!=6&&opcao>=1&&opcao在任何情况下,你都必须决定是要使用
int-opcao
还是
char opcao
。在演示问题时,始终确保你的例子遵守“最小值”在中。这意味着用最短的代码来证明混淆。很明显,案例2到6不需要(也没有代码),因此可以进行删减。但案例1中的scanf电话数量也比证明问题所需的要多。请记住,您也可以通过“编辑”来编辑您的帖子,使其更简洁、信息更丰富按钮。在
while
中,您真的是指
while((opcao!=“1”)| |(opcao!=“1”)…
?您在开关中测试的值是ASCII“1”,它=0x31或49(十进制)。是的,但如果我输入一个字母,程序就会运行indefinitly@Leonardo努内斯:“不确定的运行”是什么是什么意思?你到底观察到了什么?你需要处理这样一种情况,即你输入一个
char
,而scanf wnats一个
int
@AndreyT,它会不断重新显示m