使用Scanner-java时的一个无限循环



我想询问用户是否要创建一个名为file.elt的文件。我正在尝试使用Scanner类的switch语句来实现这一点。

这是我的代码:

    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循环是无限的,我不知道为什么。

您没有更新strOption。您应该在while循环中移动strOption=sc.nextLine();此外,正如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);
}

注意:这在eclipse中不起作用。

扫描仪是基于状态的,有点困难。我不会把它用于非象征性的事情。

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

2个选项:

  1. 因为sc.hasNext()总是真的。您需要调用sc.nextLine使该扫描仪通过当前线路

  2. sc.hasNext()正在阻止(如文件所述)

如果你能判断它是否真的是一个无限循环或阻塞调用,你就会知道如何解决它(只需在循环开始时添加跟踪,运行程序,并检查输出控制台)

首先,除非您知道自己在做什么,否则不要使用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();

最新更新