另一种方法中的Java扫描程序

时间:2016-01-24 20:00:24

标签: java

我正在为我的一个班级的实验室工作,因此我正在寻找更多的解释而不是实际的代码。

对于此作业的一部分,我需要读取用户的数字,直到按下control-d。我在方法中有一个while循环,我也将扫描器传递给方法,这是我的主要方法:

    Scanner scan = new Scanner(System.in);

    System.out.println("Length:");
    int length = 0;

    if(scan.hasNextInt()){
        length = scan.nextInt();
    }

    if(length<0 || length>100){
        System.out.println("Length is not of the proper size");
        scan.close();
        return;
    }

    Double[] a1 = new Double[length];
    Double[] a2 = new Double[length];
    fillWithZeros(a1);
    fillWithZeros(a2);

    System.out.println("Enter the numbers to be multiplied:");

    a1 = fillWithValues(a1,scan);
    a2 = fillWithValues(a2,scan);
    double total = calculateTotal(a1,a2);
    printVector(a1,"a1");
    printVector(a2,"a2");
    System.out.println("Total: " + total);
    scan.close();

然后这是我的fillWithValues方法:

public static Double[] fillWithValues(Double[] array, Scanner scan) {
    int numberOfElements = 0;
    while(scan.hasNextDouble()){
        if(numberOfElements<array.length){
            array[numberOfElements] = scan.nextDouble();
            numberOfElements++;
        }else{
            return array;
        }
    }
    return array;
}

我遇到的问题是,当我按下Control-D时,它并没有像它应该那样结束输入流,但是我在上面有代码,它会结束输入流,所以有人可以解释为什么我有这个问题吗?

我只是将扫描程序声明为全局变量,但我不允许使用全局变量进行此分配。

2 个答案:

答案 0 :(得分:0)

在上面的代码中,您正在使用

a1 = fillWithValues(a1,scan);
a2 = fillWithValues(a2,scan);

其中fillWithValues()基本上是

while(scan.hasNextDouble()){
   ...
}

这意味着,如果扫描程序观察到EOF字符(如果是Unix,则为CTRL-D),scan.hasNextDouble()将返回false并且该方法将终止 - 但是,您的程序会立即调用扫描仪将等待下一个双倍的方法(如果你再次按CTRL-D,程序最终也会在这种情况下终止)。

如果用一次循环调用替换两个方法调用,程序将在(第一个任何唯一的)循环之后恢复并终止。

要解决这个问题,你可以让方法返回boolean而不是数组(你不需要返回并重新分配数组作为返回值,因为你已经修改了数组的数组元素你作为参数传递):

public static boolean fillWithValues(Double[] array, Scanner scan) {
    int numberOfElements = 0;
    while(scan.hasNextDouble()){
        if(numberOfElements<array.length){
            array[numberOfElements] = scan.nextDouble();
            numberOfElements++;
        }else{
            return true;  // all elements read
        }
    }
    return false;   // input aborted
}

然后,调用代码可以决定是终止还是继续:

if (fillWithValues(a1,scan) == true) {
    fillWithValues(a2,scan);  // could also check the return value again if required
}

顺便说一下,只有在绝对需要时才使用static方法 - 这里没有必要。一旦整体逻辑正常工作,您应该将其作为练习来删除static方法。

答案 1 :(得分:0)

问题在于hasNextDouble()的行为nextDouble()

  

如果此扫描程序输入中的下一个标记可以,则返回true   使用fillWithValues()方法解释为double值。该   扫描仪不会超过任何输入。

首先,除非您按Enter键完成令牌,否则将永远不会读取或仔细检查 Ctrl-D 。执行此操作时,hasNextDouble()将退出,因为fillWithValues()对于任何非双输入(不仅仅是 Ctrl-D )都会返回false。其次,由于扫描程序不会超过任何输入,因此对group_tag的以下调用以相同的非双输入开始和结束,并且不会按预期读取更多的双精度数。至少你需要传递导致第一次调用停止的令牌(如果它需要 Ctrl-D 专门检查它)。