2011-11-02 68 views
0

我有一個程序的以下部分,它模擬了一個非常基本的菜單。我如何優雅地使java.util.Scanner再次等待輸入?

while (true) { 
    int selection; 
    try { 
     selection = scanner.nextInt(); 
    } catch (Exception e) { 
     selection = -1; 
    } 
    switch (selection) { 
    case 0: 
     System.exit(0); 
    default: 
     System.out.println("No valid selection!"); 
    } 
} 

現在,每當我輸入的整數,所述selection設爲-1並打印錯誤消息。然而,循環繼續不斷,Scanner不等待任何輸入。

如何讓它再次等待?如何在這裏更好地處理格式錯誤的用戶輸入?

回答

6

Scanner不能讀的東西,有問題的數據是從流,這意味着任何後續的讀取會再次失敗,直到數據刪除已清除。

爲了解決這個問題,你可以,如果失敗,只是讀的東西,而忽略結果:

try { 
    selection = scanner.nextInt(); 
} catch (Exception e) { 
    selection = -1; 
    scanner.next(); // discard the input 
} 
-3

使某些用戶輸入退出/打破while循環。就像用戶在循環停止時輸入「Exit」一樣。

除此之外,你可以這樣做:

catch (Exception e) { 
    selection = -1; 
} 
switch (selection) { 
case 0: 
    System.exit(0); 
default: 
    System.out.println("No valid selection!"); 
    System.out.println("Try again!"); 
    selection = scanner.nextInt();   
} 
+0

的問題是什麼@EtiennedeMartel描述了他的答案; 'nextInt()'不會在失敗時從掃描器中移除令牌,因此他的程序進入無限循環(就像你的那樣)。 –

+0

這不起作用。如果'nextInt()'失敗,則任何對'nextInt()'的調用都將再次失敗,直到數據從流中被移除。 –

+0

是的,這不起作用,只是拋出後續的異常。 – slhck

1

不知道拋出和捕獲的異常是否在你的情況相關。

嘗試:

boolean isValid = false; 
int selection; 
while(!isValid) { 
    isValid = scanner.hasNextInt(); 
    if(!isValid) { 
     System.out.println("No valid selection!"); 
     scanner.next(); 
    } else { 
     selection = scanner.nextInt(); 
    } 
} 
if(selection == 0) { 
    System.exit(0); 
} 
+1

這是一個相當不錯的方法,除了你的cheesy'isInteger()'方法;)'Integer.parseInt(String i)'爲你做這件事,並且如果它不是一個整數則拋出一個異常。 (這正是使用'scanner.nextInt()'時發生的情況......) –

+0

我知道,但'Integer.parseInt'不應該用於測試String是否爲int ;-)無論如何,一個是免費的以他想要的方式實現'isInteger'方法:) –

+0

Java似乎不同意你,因爲這正是'Scanner'所做的。 (我個人也同意Josh Bloch的觀點,即異常只能用於例外情況)。然而,我試圖做的一點是,約定是,如果你期待'int',可以使用'nextInt()'並捕獲異常(在catch中用'next()'丟棄該標記) 。更好的是,你可以使用'hasNextInt()'完全避免異常處理。沒有理由在這裏編寫你自己的任何實現。 –