循环扫描仪永远不会停止读取输入

时间:2017-07-25 22:09:23

标签: java java.util.scanner

我的下面的代码应该是提示用户输入数字。该部分有效,但在用户输入数字后,没有任何反应。为什么代码在用户输入数字后才停止?

public static void main(String[] args) {
    ArrayList<Double> inputs = getNumbers();
    int numberOfItemsToDrop = getLowestNumber();
    // ...
}


public static ArrayList<Double> getNumbers() {
    ArrayList<Double> inputs = new ArrayList <Double> ();

    Scanner in = new Scanner(System.in);
    System.out.println("Please enter five to ten numbers all on one line separated with spaces.");
    double vals = in.nextDouble();

    while (in.hasNextDouble()) {
        inputs.add(in.nextDouble());
    }

    return inputs;
}


public static int getLowestNumber() {
    int numberOfItemsToDrop = 0;

    System.out.println("How many of the lowest values should be dropped?");
    Scanner in = new Scanner(System.in);
    numberOfItemsToDrop = in.nextInt();

    return numberOfItemsToDrop;
}

1 个答案:

答案 0 :(得分:0)

你有两个问题: 额外的Scanner和无法区分的输入。

按照它们出现在您的代码中的顺序......

1。决斗扫描仪

作为一般规则,每个输入流只需要一个Scanner。 如果第一个Scanner“预读”以填充其输入缓冲区,那么当Scanner被垃圾收集时,这些字节将永远消失。 当下一个NoSuchElementException尝试读取不再存在的输入时,这通常会导致Scanner

请注意,这与与尝试从已关闭的输入流中读取相同 (见“java.util.NoSuchElementException - Scanner reading user input”)--- 即使输入流仍然打开,输入也会丢失。

更好的策略是只创建一个Scanner,然后将其传递给需要从中读取的每个方法:

public static void main(final String[] args) {
    final Scanner in = new Scanner(System.in);  // The one and only.
    ArrayList<Double> inputs = getNumbers(in);
    int numberToDrop = getLowestNumber(in);
    // ...
}

2。难以区分的输入

此外,您需要一种方法来确定浮点数据的结束和整数的开始。 您不能使用hasNextDouble执行此操作,因为像3这样的整数输入也非常好double。 幸运的是,您已经告诉用户您只会阅读该行的末尾,nextLine就是这样做了。

我创建了一个抛弃Scanner来读取double返回的String中的nextLine值。 (新Scanner parserScanner in不冲突,因为他们从不同的来源读取。)

public static ArrayList<Double> getNumbers(final Scanner in) {
    System.out.println(
      "Please enter five to ten numbers all on one line " +
      "separated with spaces."
    );
    final String s = in.nextLine();
    final Scanner parser = new Scanner(s);
    ArrayList<Double> inputs = new ArrayList<>();
    while (parser.hasNextDouble()) {
        inputs.add(parser.nextDouble());
    }
    parser.close();
    return inputs;
}

我使用hasNextInt检查了输入,如果它不是有效整数,则返回0

public static int getLowestNumber(final Scanner in) {
    System.out.println(
      "How many of the lowest values should be dropped?"
    );
    if (in.hasNextInt()) {
        return in.nextInt();
    }
    return 0;
}

我认为两种扫描方法应该如果遇到虚假输入就会抛出异常,而不是试图像这样做... 唯一比伪造数据更糟糕的是基于伪造数据的合理结果。