更新代码
为什么输入12有效?它将12解释为选项1,并在案例的第一次扫描中取2作为' 1&#39 ;?我不想使用int opcao,好像我输入了一个无限期运行的内容。
我希望用户只能在选择退出选项时退出程序(其中一个案例),因此do ... while。如果用户输入无效字符或者leter或者菜单再显示的内容,则显示默认消息。我还希望在执行所选案例之后,它再次显示菜单以进行新选择,因此我在while时使用1 = 1的始终有效条件。我不能使用整数,好像你进入了一个程序去疯子a.k.a永远不会停止运行。试试吧。
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);
答案 0 :(得分:0)
那是因为你用一个%c
来阅读你的输入。
这样,交换机使用12(1)的第一个字符,而case '1':
的scanf使用第二个字符。
要避免此行为,您可以将选项作为整数阅读,并在第一个%d
中使用占位符scanf
。
修改强>
为了避免你的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);
}
我所做的是以下内容:
clean_stdin
(Credits)清除scanf读取但未消耗的字符(它需要一个数字并给它一个字符,因此字符保留在stdin中并创建无限循环)main()
因为我需要它来运行程序;你可以在main
中加入内部的内容。请记住复制clean_stdin()
功能。我建议您阅读一些scanf documentation以了解其返回值。
我建议您阅读有关scanf
替代方案的内容,因为这是一项无聊的功能:link 1和link2。
请记住使用正确的缩进格式化代码,这是最佳做法。
答案 1 :(得分:0)
scanf
的工作原理。
您要求scanf
从输入流中读取单个字符。输入流最初包含12
序列(更可能是12<newline>
序列)。所以,就像你问的那样,scanf
消耗了第一个1
,剩下的就留在了输入流中。
下一个scanf
继续消耗前一个输入流的输入流。
答案 2 :(得分:0)
scanf
的 %c
可以同时读取一个字符。 &#39; 12&#39;包含两个字符&#39; 1&#39;和&#39; 2&#39;。所以&#39; 1&#39;将由scanf
首先消耗,因此case '1':
被执行。 &#39; 2&#39;保留在输入缓冲区(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