2013-03-16 50 views
1

這裏是我的代碼,我的陳述是,while循環開始運行show選項並在第一次迭代時掃描選擇,但在第二次迭代中,不會再次指定選擇,並且會記住先前的選擇。問題是什麼 ? (我正在使用VS2012)C項目scanf()

while (!done){ 
    int choice; 

    printf("\n------- STUDENT INFORMATION SYSTEM MAIN MENU --------\n"); 
    printf("1-Load students from the database\n"); 
    printf("2-Print existing students on the screen\n"); 
    printf("3-Add a new student\n"); 
    printf("4-Delete an existing student\n"); 
    printf("5-Find an existing student\n"); 
    printf("6-Quit\n"); 
    printf("====> Choice? "); 
    scanf("%d", &choice); 

    switch(choice){ 
     case 1: 
     LoadStudentsFromDatabase(); 
     printf("Students loaded from database successfully\n"); 
     break; 

     case 2: 
     PrintExistingStudentsOnTheScreen(); 
     break; 

     case 3: 
     printf("\nFirstName: "); scanf("%s", s.firstName); 

    printf("LastName: "); scanf("%s", s.lastName); 
     printf("ID: "); scanf("%d", &s.id); 
     printf("Gpa: "); scanf("%f", &s.gpa); 
     printf("Department: "); scanf("%d", &s.department); 

     AddStudent(&s); 
     printf("1 student added\n"); 
     break; 

     case 4: 
     printf("\nID? "); scanf("%d", &id); 
     if (DeleteStudent(id)){ 
      printf("Student deleted successfully\n"); 
     } else { 
      printf("Failed to delete the student. Does not exist?\n"); 
     } /* end-else */ 
     break; 

     case 5: 
     printf("\nID? "); scanf("%d", &id); 
     ps = FindStudent(id); 
     if (ps == NULL){ 
      printf("Student not found\n"); 
     } else { 
      char *depts[] = {"CS", "EE", "IE", "CE", "ME"}; 
      printf("+--------------------+--------------------+------+------+------+\n"); 
      printf("| FirstName  |  LastName  | ID | GPA | Dept |\n"); 
      printf("+--------------------+--------------------+------+------+------+\n"); 
      printf("|%20s|%20s|%6d|%6.2f|%6s|\n", ps->firstName, ps->lastName, ps->id, ps->gpa, depts[ps->department]); 
      printf("+--------------------+--------------------+------+------+------+\n"); 
     } //end-else 
     break; 

     case 6: 
     done = 1; 
     break; 

     default: 
     printf("!!!!!!!!!! Invalid choice. Try again :-))\n"); 
     break; 
    } /* end-switch */ 
    } /* end-while */ 
+1

你真的應該驗證scanf調用的返回值(事實上,在''',例如'if(scanf(「%d」,&choice)!= 1)/ * error * /;' – pmg 2013-03-16 09:53:45

+0

我無法重現您描述的行爲。你能想出一個SSCCE(http://sscce.org/)嗎? – NPE 2013-03-16 10:04:10

+2

[您的ideone代碼(我的SSCCE)](http://ideone.com/mwzH4f)的行爲如預期! – pmg 2013-03-16 10:23:07

回答

0

可能發生的情況是當您第二次調用scanf時出現錯誤。可能是因爲一個非數字輸入等待在stdin上讀取。也許你上次在你的代碼體內沒有完全讀取所有輸入內容?由於您的轉換格式012f,scanf會嘗試讀取一位數字和一位數字,因此如果要讀取的下一個數據不是數字,則會失敗,它會返回錯誤並保持choice不變。你不檢查這個錯誤,所以假設choice包含一個新輸入的值,實際上它只是包含scanf被調用之前包含的任何值。 scanf也可能會因爲更多的錯誤而失敗,但我懷疑這種情況並非如此。

我的建議是:

a)檢查scanf的返回值。它應該返回1在你的情況。如果它不存在錯誤。您可以退出或再次出現菜單。

b)看看fpurge/fflush。我不確定使用VC++可以獲得什麼,但Google會發現您是等同的。這些函數可用於在調用scanf之前丟棄未決的輸入。

HTH

0

實際上,您的代碼的行爲與預期相同。

行爲可以用下面的輸入轉載

FirstName: f 
LastName: l 
ID: 1 
Gpa: 2 
Department: d 

Department預計的int作爲輸入,當你在別的東西,d在這種情況下鍵入時,scanf不斷尋找一個int因爲你是循環,因此行scanf("%d", &choice);也無法讀取int,並且choice未重新分配新值,因此switch語句始終會看到choice的最後一個有效值。該循環在下次讀取嘗試時暫停。

要解決您的問題,您需要驗證輸入並且只有在您期望的輸入有效時才轉到下一步。你可以通過檢查scanf的返回值來做到這一點,女巫是根據轉換模式成功解析的項目數量,在你的情況下,你只需要閱讀one項目。

下面是一個基本方式,你如何能驗證一個整數輸入

int read_integer(char* what) 
{ 
    int i = 0; 
    printf("%s: ", what); 
    int r = scanf("%d", &i); 
    while(r == 0) { 
     while('\n' != getchar()) 
      // consume the rest of input until a LF comes (enter pressed) 
      ; 
     printf("Bad input for %s, try again (r=%d)\n", what, r); 
     printf("%s: ", what); 
     r = scanf("%d", &i); 
    } 
    return i; 
} 

,在這裏你怎麼能讀Department

int department = read_integer("Department"); 

你也可以寫一個類似的功能float - >float read_float(char*){...}