2016-01-24 48 views
4

我正在为我的一个类的实验室工作,因此我正在寻找更多的解释,而不是实际的代码。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它不会像它应该结束输入流,但我有上面的代码在主要它会结束输入流,所以有人可以解释为什么我有这个问题?

我只是将扫描仪声明为全局变量,但我不允许在此任务中使用全局变量。

+0

如果您在其他代码变体的主要方法中也有独立方法中的**精确**代码,则其行为应该相同。请发布两种变体的完整代码,工作人员和非工作人员(另请参见[mcve])。 –

+0

我编辑过它显示我的代码为主,然后是不工作的方法。如果我将fillWithValues方法中的代码放在main中,并将数组名称更改为a1或a2而不是数组,则它工作得很好 –

+0

因此,您正在用**替换** two **'fillWithValues()'调用**来自该方法的一个**代码块? –

回答

0

在上面的代码中,使用的是

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

其中fillWithValues()基本上不

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

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

如果更换法一个调用循环的来电,PROGRAMM将刚刚恢复(第一只任意)循环后终止。

为了解决这个问题,你可以让方法返回一个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 
} 

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

0

的问题是与hasNextDouble()行为,从documentation

返回true,如果在此扫描器输入信息的下一个标记可以 解释为使用nextDouble()方法的双重价值。 扫描仪不会超过任何输入。

所以第一关,按Ctrl-d本身将永远不会被读取或审查,除非你按enter完成令牌。当你这样做时fillWithValues()将退出,因为hasNextDouble()对于任何非双输入(不仅仅是Ctrl-D)返回false。其次,由于扫描仪不会超过任何输入,因此以下呼叫fillWithValues()开始并以相同的非双输入结束,并且不会像您期望的那样读取更多双打。至少你需要传递导致第一次通话停止的令牌(并且如果它需要Ctrl-D专门检查那个)。