【问题标题】:Java Scanner won't "finish" reading inputJava Scanner 不会“完成”读取输入
【发布时间】:2012-04-06 16:48:49
【问题描述】:

我在使用 java 的 Scanner 类时遇到了问题。我可以让它很好地读取我的输入,但问题是当我想输出一些东西时。给定多行输入,我想在完全读取所有输入后只打印一行。这是我用于读取输入的代码:

    public static void main(String[] args){
    Scanner scanner = new Scanner(System.in);   //scanner reads block of input
    while(scanner.hasNextLine()){    
        //body of loop goes here
        String s = scanner.nextLine();
        Scanner ls = new Scanner(s);   //scanner to parse a line of input
        while(ls.hasNext()){
        //body of nested loop goes here
        ls.next();
        }
    }
    System.out.println("Fin");
    }

即使已读取所有输入行,程序也不会到达 System.out.println 消息。 (请注意,消息不能发送到其他任何地方,否则它将输出与循环运行一样多的次数)。我该如何解决?任何帮助将不胜感激。

【问题讨论】:

  • 你能在两个while循环中放一些错误检查打印并告诉我它卡在哪一个吗?
  • 我尝试在每个循环中放置打印,但它似乎并没有无限循环,而是更像外部 while 循环无限等待更多输入
  • 有人在下面发现了这一点。

标签: java while-loop java.util.scanner


【解决方案1】:

正如我在您使用的外部 while 循环中看到的那样

scanner.hasNextLine();

方法。如果必须等待输入,此方法将被阻止。你也有

Scanner scanner = new Scanner(System.in);

声明。所以 system.in 将一直等待输入,因此 hasNextLine() 方法必须等待输入。 这就是控件卡在循环中而无法继续进行的原因。

要修复它,您可以首先将输入存储在字符串变量中,然后调用扫描仪构造函数。

【讨论】:

  • 但是我会在字符串变量中存储什么?程序必须从控制台读取,如果我将输入的行保存为字符串,程序会不会仍然等待新的输入行?
【解决方案2】:

在这种情况下,您正在从无限流中读取。如果此扫描仪的输入中有另一行,hasNextLine() 将继续返回 true。作为System.in,它将继续从键盘读取,除非您终止它或告诉流停止。

最后按“ctrl+Z”,你会看到它起作用了。

编辑:你可以做这样的事情......

Scanner scanner = new Scanner(System.in);   //scanner reads block of input
        int BLOCK_SIZE  =3,count=1;
        while(scanner.hasNextLine()){    
            //body of loop goes here
            String s = scanner.nextLine();
            Scanner ls = new Scanner(s);   //scanner to parse a line of input
            while(ls.hasNext()){
            //body of nested loop goes here
            ls.next();
            }
            if(count++==BLOCK_SIZE)
            {
                break;
            }
        }
        System.out.println("Fin");

    }

【讨论】:

  • 那么,一旦所有输入都被读取,有没有办法以编程方式阻止它读取?
  • 你的程序如何知道它现在应该停止?
  • 它不知道,这就是问题所在。当我希望在读取所有输入后输出它时,它只是一直等待另一行输入。
  • 如果我有一个输入块,比如 3 行文本,我希望它在读取第三行后停止
【解决方案3】:

您需要告诉程序不再有输入。这是通过附加一个 EOF 字符来完成的。这可以通过在控制台中按 Ctrl-D 在 Linux 上手动完成。我认为在 Windows 上您可以按 Ctrl-Z。如果您将输入从一个程序传递到另一个程序,则流将自动关闭。

例如。

cat filename | java MyJavaProgram

【讨论】:

    【解决方案4】:

    魔法

    Scanner scanner = new Scanner(System.in);
        while(scanner.hasNextLine()){ 
    

    是否永远不会停止从系统输入(除非您使用 ctrl+d 关闭输入(对于 mac))。

    要停止循环,我建议在条件中添加更多内容,而不仅仅是 hasNextLine()。

    例如

    Scanner scanner = new Scanner(System.in);   //scanner reads block of input
        int BLOCK_SIZE  =3,count=1;
        while(scanner.hasNextLine() && count++ <= BLOCK_SIZE){   //<- Use count here.
            //body of loop goes here
            String s = scanner.nextLine();
            Scanner ls = new Scanner(s);   //scanner to parse a line of input
            while(ls.hasNext()){
            //body of nested loop goes here
            ls.next();
            }
        }
        System.out.println("Fin");
    
    }
    

    【讨论】:

    • 这毫无意义。 总是 评估为真的布尔属性有什么意义。有些东西没有加起来。我错过了什么?
    • @NathanToulbert 你是对的,我在 7 年前写了这个答案,我被提问者的现有代码所吸引。如果您打算终止系统输入,则只需要hasNextLine
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    相关资源
    最近更新 更多