【问题标题】:Continue reading console input after Ctrl+Z in JavaJava中Ctrl+Z后继续读取控制台输入
【发布时间】:2014-11-20 17:28:23
【问题描述】:

对于大学作业,我需要能够从控制台读取多行内容,直到用户输入 Ctrl+Z。我没有问题,我的问题在于我无法从 System.in 中读取任何内容,因为它总是抛出 NoSuchElementException。

以下是我用于多行阅读的代码,由讲师提供,因此我不想更改。

System.out.println("To terminate input, type the correct end-of-file indicator ");
System.out.println("when you are prompted to enter input.");
System.out.println("On UNIX/Linux/Mac OS X type <ctrl> d");
System.out.println("On Windows type <ctrl> z");

Scanner input = new Scanner(System.in);

while (input.hasNext()) {
    //Processes input
    addFileIntoDirectory(input.nextLine());
}

我知道这是由相当于 EOF 标记的 Ctrl+Z 引起的,但我不知道如何越过它。无论我读了多少次,无论我是否在控制台输入了更多内容,我都会立即返回另一个 NoSuchElementException。

我尝试为菜单设置一个单独的扫描仪,关闭上面的扫描仪并为菜单打开一个新的扫描仪,但都不起作用。

有没有办法刷新/清除 System.in 或重置它?

如果您想了解更多详情,请告诉我。由于是家庭作业,我对程序的其余部分保持模糊。

编辑 1: 作业说“系统提供如下文本选择菜单,并且 循环运行。”这意味着程序不会在 Ctrl+Z 时终止。

  1. 从用户输入添加文件
  2. 显示整个目录
  3. 显示目录大小
  4. 退出 请选择 [0-4]:

【问题讨论】:

  • 文件结束是文件结束,句号。那个流已经结束了。这是一个前流。但是,我认为您可能误解了您的任务。你还没有写出它到底是什么。但我在想,如果你应该有一个菜单,然后是一系列输入,然后返回菜单 - 那么 eof 应该作为 program 的结尾,而不是输入结束。
  • @RealSkeptic 这就是我想要的,但菜单有一个“退出”选项,所以我被引导相信情况并非如此。
  • 尽管如此,在你的问题中写下作业的完整和准确的文本。如果我们不知道实际需求,有很多解释的可能性......
  • 是全文吗?然后它什么也没说Ctrl-Z。也许你应该忽略它。或者你应该说出作业的全文是什么。我仍然认为你在误解它。

标签: java java.util.scanner


【解决方案1】:

简短的回答是:

if (!input.hasNext())
    input = new Scanner(System.in);

长答案是:

以下是代码,其中包含用于稍后删除的 cmets,以演示我理解的问题和解决方案。

请注意,此演示仅适用于使用整数和^Z 输入。

复制代码并保存到文件HN.java进行编译。

运行程序,会提示一个。输入您喜欢的整数并通过输入^Z 退出循环。

两个将在问题中显示,然后是NoSuchElementFound exception。这是因为 ^Z 保留 在 Scanner 对象 input 中,因此在 nextInt() 方法上失败。

第一个倾向可能是使用hasNext() 来解决这个问题。所以继续取消注释/*Comment1 并重新编译并再次运行。

现在您避免了异常,但程序一直运行到最后,跳过了最初打算使用的 nextInt()

现在,取消注释/*Comment2,重新编译,然后再次运行。现在程序将按预期在 Two 提示符处等待。如果您在此处输入一个整数,您将进入 提示输入另一个条目。

但是,如果您在 Two 处再次输入 ^Z,程序将跳过下一个输入。要更正此问题,请取消注释 /*Comment3,重新编译并运行,您将看到该程序适用于各种输入的所有整数组合和 ^Z

现在,您可能想知道为什么我不只是在/*Comment3 中重用!input.hasNext() 解决方案。这是一个演示原因:

放回/*Comment3,取消/*Comment4的注释,再次编译运行。该程序在 Two 提示符处输入 ^Z 时运行良好且花花公子,但如果您在此处输入整数,您将看到系统等待输入,但没有提示符三个

这是因为您输入的整数在前面的nextInt() 中使用过,所以当程序到达hasNext() 时,它会停止并等待输入。

这里的教训是当你知道你有一个^Z 时使用!input.hasNext() 在队列中 例如当它被用来逃避这个程序中的while循环和原始发布者的问题时.否则 else 结构更适合。

hasNext() 令人困惑。您必须记住,如果队列中没有任何内容,程序将在此时停止并等待输入。如果您不小心,这可能会打乱您的提示。

import java.util.Scanner;

public class HN
{
    public static void main(String args[])
    {
        Scanner input = new Scanner(System.in);
        int temp = 0;

        System.out.println("One");

        while (input.hasNext())
        {
            temp = input.nextInt();
        }

        System.out.println("Two");

        /*Comment2
        if(!input.hasNext()) input = new Scanner(System.in);
        Comment2*/

        /*Comment1
        if (input.hasNext())
        Comment1*/

        {   
            temp = input.nextInt();
            System.out.printf("%d\n", temp);
        }

        /*Comment3
        else input = new Scanner(System.in);
        Comment3*/

        /*Comment4
        if(!input.hasNext()) input = new Scanner(System.in);
        Comment4*/

        System.out.println("Three");

        if (input.hasNext()) 
        {   
            temp = input.nextInt();
            System.out.printf("%d\n", temp);
        }

        System.out.println("Four");
    }
}

【讨论】:

  • 这是一个非常糟糕的答案...添加一些单词和一些格式。
  • 按要求详细说明:
  • 上面的行可用于“摆脱”扫描仪对象“输入”中的 ^Z。在下一次读取之前插入该行。但是请注意,如果根本没有数据,Scanner 对象“输入”将在这一行暂停执行并等待输入。
  • 这变成了一个非常好的答案;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
相关资源
最近更新 更多