2015-10-25 40 views
1

我正在爲我的課程開發一個程序,要求我從txt文件中讀取數據,然後再顯示出來。我創建了一個爲hasNext讀取的while循環,但我遇到了一個異常。它說這是一個「沒有這樣的元素例外」,我不知道爲什麼。該循環對於5次重複,則給了我異常基本文件掃描程序異常/問題

import java.util.Scanner; 
import java.text.DecimalFormat; 
import java.io.*; 

public class Project2_William_Walker 
{ 
    public static void main (String[]args) throws IOException 
    { 
     File file = new File ("boarding.txt"); 
     Scanner inputFile = new Scanner(file); 
     DecimalFormat df = new DecimalFormat("0.00"); 

     String title = "Madison Kennel & Grooming"; 
     String fName; 
     String lName; 
     String breed; 
     String weight; 
     String age; 
     double highRisk = 20.00; 




     while (inputFile.hasNext()) 
     { 
     fName = inputFile.nextLine(); 
     lName = inputFile.nextLine(); 
     breed = inputFile.nextLine(); 
     weight = inputFile.nextLine(); 
     age = inputFile.nextLine(); 

     inputFile.nextLine(); 

     System.out.println(fName + " " + lName + " " + breed + " " + weight + " " + age); 
     System.out.println(); 



     } 
     inputFile.close();  

     System.out.println("End of Program"); 

    } 
} 

所以在我的txt文件我有了一個名字,然後一個姓氏列表,其次是品種,重量,然後歲。看起來像這樣:

Will 
Walker 
Pug 
3 
4 

John 
Appleseed 
Retriever 
15 
7 

..等等4個條目。我的循環獲得了前5名的好成績,但是在第6名和最後一次通過了。謝謝你的幫助!

+0

請注意,如果您有關於異常的問題,發佈整個異常及其堆棧跟蹤非常重要。所以,請添加到你的問題。 – Tom

回答

1

您正在閱讀在環路線,但如果有(至少)要讀取行循環條件僅檢查。

您可能在輸入文件末尾有一個額外的空白行,導致hasNext()在讀入最後一個數據塊後返回true

您最好使用for循環迭代5次,每次檢查是否有一行可用,並且每次將數據保存到數組中。

喜歡的東西:

String[] data = new String[5]; 

while (inputFile.hasNext()) { 
    Arrays.fill(data, null); // clear out array, in case input is short 
    for (int i = 0; i < 5 && inputFile.hasNext(); i++) 
     data[i] = inputFile.nextLine(); 

    if (inputFile.hasNext()) 
     inputFile.nextLine(); 

    System.out.println(data[0] + " " + data[1] + " " + data[2] + " " + data[3] + " " + data[4]); 
    System.out.println(); 
} 
inputFile.close();  
+0

*「,但循環條件只檢查是否有(至少)1行讀取」*如果最後一個塊不僅包含_five_行,這不會是一個問題(但仍是代碼異味並容易出錯)。 ..:P。而這個*「你可能在輸入文件末尾有一個空行」*會解決他的問題。 – Tom

+0

請注意,此代碼不會解決OP問題。 – Tom

+0

@Tom oops!你是對的。我完全忘記了需要額外的檢查。希望現在看起來更好。 – Bohemian

1

讓我們找到你的問題的根源。做到這些,讓我們的「地圖」你nextLine()調用文件內容:

Iteration Code        Read line from file 

    1  fName = inputFile.nextLine();  Will 
    1  lName = inputFile.nextLine();  Walker 
    1  breed = inputFile.nextLine();  Pug 
    1  weight = inputFile.nextLine(); 3 
    1  age = inputFile.nextLine();  4 
    1  inputFile.nextLine();    (empty line between blocks) 
    2  fName = inputFile.nextLine();  John 
    2  lName = inputFile.nextLine();  Appleseed 
    2  breed = inputFile.nextLine();  Retriever 
    2  weight = inputFile.nextLine(); 15 
    2  age = inputFile.nextLine();  7 
    2  inputFile.nextLine();    

正如你所看到的,inputFile.nextLine()嘗試最後的語句從文件中讀取一條線,但並沒有什麼更多的再閱讀,因爲「7」是最後一行。所以你的問題是,你期望有一個總是一個空白的行後塊。

速戰速決將增加一個檢查,如:

if (inputFile.hasNextLine()) 
    inputFile.nextLine(); 

但是這可能會導致麻煩,如果沒有空行拆分兩個街區,下一個塊中的最後一個之後立即開始。

爲了避免這樣的問題,我首先推薦一個不同的文件結構。比如,你可以使用csv用 「」 作爲分隔符:

意志,沃克,帕格,3,4
約翰,蘋果核戰,獵犬,15,7

而且閱讀它是這樣的:

final String line = inputFile.nextLine(); // read a single line 
final String[] items = line.split(","); // split that line using ',' 
fName = items[0]; 
lName = items[1]; 
breed = items[2]; 
weight = items[3]; 
age = items[4]; 
System.out.println(fName + " " + lName + " " + breed + " " + weight + " " + age); 

,並使其更好:創建持有必要的字段來表示這樣的行(或你的前檔風格的塊)的模型類,並讓CSV讀者喜歡Jackson d o爲你解析。

+0

這正是我的問題!十分感謝你的幫助!把它映射出來真的很有幫助,我對編程真的很陌生,所以通過可視化我可以馬上看到我的問題。 –