2014-09-24 123 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