2012-12-26 58 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); 
} 

希望它幫助。