2012-12-26 28 views
1
#include <stdio.h> 
void load_menu(void); 

int main(void) 
{ 
    load_menu(); 
    return 0; 
} 

void load_menu(void) 
{ 
int choice; 
int loopagain; 

do 
{ 
    printf("Menu \n\n"); 
    printf("Please enter your choice: \n"); 
    printf("1. \n"); 
    printf("2.\n"); 
    printf("3.\n"); 
    printf("4. Exit\n"); 
    if (scanf("%d",&choice)==1) 
    { 

     switch(choice) 
     { 
      case 1: 
        break; 
      case 2: 
        break; 
      case 3: 
        break; 
      case 4: printf("Quitting program!\n"); 
        break; 
      default: printf("Invalid choice! Please try again\n"); 
        printf("\n"); 
       break; 
     } 
    } 

    else 
    { 
     printf("Characters are invalid, please enter a number: \n "); 
     if (scanf("%d",&loopagain)==1) 
      load_menu(); 
    } 

}while((choice !=4)); 
} 

为什么当我输入一个字符时,这仍然给我一个无限循环?这是一个菜单(案例陈述仍需要填写),但我正在照顾由if语句输入的字符,但它似乎仍然不起作用。谢谢给我一个无限循环的代码

+4

递归调用看起来是非常不必要的.. – StoryTeller

+0

即使我怀疑你的意思也是使用递归,或者理解为什么这是不好的(在这种情况下) –

+0

回滚“它已解决”。更改。如果问题解决了,请选择一个答案或添加解决问题的答案。 –

回答

4

如果字符输入无效,则新调用的load_menu()中的loopagain将与其调用者中的loopagain不同。当您输入的东西是不是一个数字,因此不被接受scanf("%d",&choice)输入缓冲器不刷新

else 
{ 
    printf("Characters are invalid, please enter a number: \n "); 
    choice = 0; // Unused, so continue the loop 
} 
+0

我安排了它,但如果输入不是整数,它仍然会给出无限循环 – user1930901

+0

@ user1930901:“无限”如何?如果你继续输入非整数,那么不,它不会结束... – Ryan

+0

我安排了无限循环,但现在如果我输入一个字符,它只是显示字符无效,并没有给我一个重新输入的机会一个整数。这就是为什么我使用load_menu两次 – user1930901

0

:不循环的。我相信在处理不可接受的输入时,您应该能够通过致电fflush(stdin)解决此问题。更好的是,每次调用scanf之后,您可能会更好地刷新输入缓冲区。

在我看来,处理不正确的输入是没有意义的。它应该像你的default:案件一样处理,我想。正如其他人所说的,递归调用没有意义,当您要返回显示菜单并再次获取用户输入时,也不会再次调用scanf以进行输入。

+0

正如我在几秒前发布的链接中所解释的,fflush(stdin)_ONLY_在具有正确C库的特定平台上工作。例如在Linux中,它不起作用(并且它是未定义的,所以编译器生成代码时完全合法 - 如果你这样做 - 我不相信这是可能的,但这不是没有可能) –

1

我相信,除了迄今为止发现的问题之外,有问题的“字母”会卡在输入缓冲区中。当用scanf读取一个数字时,只要它碰到任何不是白色而不是数字的东西就会停下来。因此,如果缓冲区包含“a \ n”,并且我们调用scanf("%d", ...),那么scanf将返回immediatelty,并将继续这样做,直到从缓冲区中删除“off”为止。

我们需要的是一个小小的循环来从输入缓冲区中删除有问题的“垃圾”。

这里是一个问题(虽然冲洗是一个稍微不同的原因,解决的办法是一样的)前问: Question about flushing buffer

0

我觉得你的问题是loopagain变量。通过这个名字,你正在考虑这个变量,就像一个标志一样循环或者不再循环,并且管理你的第二个循环的方式。既然你是从stdin(scanf)读取它,你将失去对它的控制。 由于您的实现中已经有一个scanf,并且由于它是一个循环,所以您不需要递归调用,并且可以始终使用相同的scanf,并以正确的方式使用loopagain变量/标志。 甚至更​​好的是,除了EOT(ascii-cntr-D)之外,没有字符,它的整数值是4(它绝对不会通过scanf测试,值为1,但仍然...) - 一般的,你可以把它看作是打破你的程序的另一种方式。

一个soluiton这是(我想,我的解释):

#include <stdio.h> 
    void load_menu(void); 

    int main(void) 
    { 
     load_menu(); 
     return 0; 
    } 

    void load_menu(void) 
    { 
    int choice; 
    int loopagain = 1; 

    do 
    { 
     if(loopagain != 0){ /*You'll set it to different from 0 if the user entered a 'bad' number so the menu is only printed once*/ 
      printf("Menu \n\n"); 
      printf("Please enter your choice: \n"); 
      printf("1. \n"); 
      printf("2.\n"); 
      printf("3.\n"); 
      printf("4. Exit\n"); 
     } 
     if (scanf("%d",&choice)==1) 
     { 

      switch(choice) 
      { 
       case 1: 
         break; 
       case 2: 
         break; 
       case 3: 
         break; 
       case 4: printf("Quitting program!\n"); 
         break; 
       default:printf("Invalid choice! Please try again\n"); 
         loopagain = 0; 
         printf("\n"); 
        break; 
      } 
     }else{ 
      printf("Characters are invalid, please enter a number: \n "); 
      loopagain = 0; 
     } 

    }while(choice !=4); 
} 

希望它帮助。