2014-09-24 119 views
-3

我想問用戶他是否想要創建一個名爲file.elt的文件。我正在嘗試使用Scanner類的switch語句來完成此操作。使用掃描儀時無限循環 - java

這裏是我的代碼:

System.out.println("Do you want to create the file.elt? (Y/N)"); 
      strOption=sc.nextLine(); 

     OUTER: 
     while (sc.hasNext()) { 
      switch (strOption) { 
       case "Y": 
       case "y": 
        elements.createElements(file); 
        break OUTER; 
       case "N": 
       case "n": 
        System.out.println("There will be no file.elt created! ."); 
        break OUTER; 
       default: 
        System.out.println("Please, type Y or N."); 
        strOption=sc.nextLine(); 
        break; 
      }     
     } 
     sc.close(); 

sc對象在程序中,在那裏我要求的文件的名稱的開頭聲明。

sc聲明:

String file; 

    Scanner sc = new Scanner(System.in); 

    System.out.println("Type the name of the file .dat ."); 

    file=sc.nextLine(); 

的問題是,while循環是無限的,我不知道爲什麼。

回答

5

您沒有更新strOption。 您應將strOption=sc.nextLine();移動到您的while循環中 此外,正如TheLostMind所指出的那樣,將hasNext替換爲hasNextLine


編輯

你可能會考慮切換到Console。此外,您可以創建confirm實用的方法,因爲它是相當常見的任務:

private Console console; 

... 
console = System.console(); 
... 
if (confirm("Do you want to create the file.elt? (Y/N)")) { 
    elements.createElements(file); 
} else { 
    System.out.println("There will be no file.elt created! ."); 
} 
... 

private boolean confirm(String message) { 
    String answer = console.readLine(message); 
    while (!answer.matches("[YyNn]")) { 
     answer = console.readLine("Please, type Y or N."); 
    } 
    return "Y".equalsIgnoreCase(answer); 
} 

注:此doesn't work in eclipse

+1

也改變'sc.hasNext()''到sc.hasNextLine()' – TheLostMind 2014-09-24 10:20:14

+0

太好了!謝謝! – daro 2014-09-24 10:22:19

1

掃描儀是基於狀態的,並且有點困難。我不會將它用於非標記的東西。

//strOption=sc.nextLine(); 
OUTER: 
while (sc.hasNextLine()) { 
    strOption=sc.nextLine(); 
... 
     default: 
      System.out.println("Please, type Y or N."); 
      //strOption=sc.nextLine(); 
1

2個選擇:

  1. 因爲sc.hasNext()總是正確的。你需要調用sc.nextLine來此掃描器執行當前行

  2. sc.hasNext()阻塞(如描述的documents

如果你愛泰克告訴我們,如果這是真的一個無限循環或阻塞call - 你將知道如何解決它(只需在循環開始時添加跟蹤,運行程序並檢查輸出控制檯)

1

首先,除非您知道自己在做什麼,否則請勿使用標籤,例如OUTER。在這種情況下,它不是必需的。

sc.hasNext()返回true(否則你甚至不會進入循環),並且在循環中你不會做任何改變該狀態的操作(你不會「消耗」輸入流)。

甚至在進入循環之前,您會讀取第一行,之後顯然會有更多輸入被讀取,但您從不讀取該輸入,因此sc.hasNext()始終返回true,while循環從未結束。

您的break OUTER;中斷到OUTER:中定義的循環,這意味着它打破了while循環,不是while循環的OUT。通常人們使用這個構造來將內部循環分解爲外部循環,但正如我之前所說的,你最好不要使用這個構造。

編輯:我混淆標記休息與標記繼續。基本上,這裏的突破按預期工作,但標籤是多餘的(我仍然建議不要使用標籤)。

接下來的問題是,由於某些原因,您讀取的第一行輸入可能不等於「y」,「Y」,「n」或「N」,並且由於您沒有使用輸入, sc.hasNext()strOption仍包含相同的字符串,它不等於您的任何case語句,這意味着循環將無限次地繼續。

請使用普通的break;修復循環,以便消耗輸入。

例如:

System.out.println("Do you want to create the file.elt? (Y/N)"); 

while (sc.hasNext()) 
{ 
    String inputString = strOption=sc.nextLine(); 
    // handle inputString   
} 
sc.close(); 
+1

帶標籤的中斷將*分割爲外部循環,但由於外部循環立即結束,所以在大多數情況下,它等價於外部循環的break * out *。 (請參閱http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.15) – 2014-09-24 10:49:37

+0

感謝您的提示!事實上,我從來沒有使用過標籤......謝謝你!正如你所看到的,我在Java編程方面很新穎。 – daro 2014-09-24 12:31:45

+0

@ThomasStets你是對的。我把帶標籤的休息與帶標籤的繼續混淆了 – Buurman 2014-09-25 12:51:03