2016-01-24 76 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專門檢查那個)。