2015-11-26 80 views
2

我想要做的是讀取一個有人類和動物的文本文件。它會編譯,但當我嘗試運行它時會出錯。我想我需要一個for循環來讀取stringtokenizer來解釋txt文件中的人類和動物之間的關係,到目前爲止,這是我的驅動程序類。在java中讀取一個特殊的txt文件

txt文件:

Morely,Robert,123 Anywhere Street,15396,4,234.56,2 
Bubba,Bulldog,58,4-15-2010,6-14-2011 
Lucy,Bulldog,49,4-15-2010,6-14-2011 
Wilder,John,457 Somewhere Road,78214,3,124.53,1 
Ralph,Cat,12,01-16-2011,04-21-2012 
Miller,John,639 Green Glenn Drive,96258,5,0.00,3 
Major,Lab,105,07-10-2012,06-13-2013 
King,Collie,58,06-14-2012,10-05-2012 
Pippy,cat,10,04-25-2015,04-25-2015 
Jones,Sam,34 Franklin Apt B,47196,1,32.09,1 
Gunther,Swiss Mountain Dog,125,10-10-2013,10-10-2013 
Smith,Jack,935 Garrison Blvd,67125,4,364.00,4 
Perry,Parrot,5,NA,3-13-2014 
Jake,German Shepherd,86,11-14-2013,11-14-2013 
Sweetie,tabby cat,15,12-15-2013,2-15-2015 
Pete,boa,8,NA,3-15-2015 

來源:

import java.util.Scanner; 
import java.util.StringTokenizer; 
import java.io.File; 
import java.io.IOException; 
/** 
* This is my driver class that reads from a txt file to put into an array and uses the class refrences so it can use the menu and spit out 
* 
* @author ****** 
* @version 11/25/2015 
*/ 
public class Driver 
{ 
    /** 
    * Constructor for objects of class Driver, what it does is read in the txt file gets the two class refrences and loops through to read through the whole file looking for string tokens to go to the next line 
    * and closes the file at the end also uses for loop to count number of string tokens to decipher between human and pets. 
    */ 
    public static void main(String[] args) throws IOException 
    { 
     Pet p; 
     Human h; 
     Scanner input; 
     char menu; 
     input = new Scanner(new File("clientdata.txt")); 

     int nBalance; 
     int id; 

     /** 
     * this while statement goes through each line looking for the string tokenizer ",". I want to count each "," to decipher between Human and Animal 
     */ 
     while(input.hasNext()) 
     { 
      StringTokenizer st = new StringTokenizer(input.nextLine(), ","); 
      h = new Human(); 
      h.setLastName(st.nextToken()); 
      h.setFirstName(st.nextToken()); 
      h.setAddress(st.nextToken()); 
      h.setCiD(Integer.parseInt(st.nextToken())); 
      h.setVisits(Integer.parseInt(st.nextToken())); 
      h.setBalance(Double.parseDouble(st.nextToken())); 
      p = new Pet(st.nextToken(), st.nextToken(), Integer.parseInt(st.nextToken()), st.nextToken(), st.nextToken()); 
     } 
     /** 
     * this is my seond while statement that loops the case switch statements and asks the user for client ID 
     */ 
     menu = 'Y'; 
     while(menu == 'y' || menu == 'Y') { 
      System.out.print("\nChose one:\n A- client names and outstanding balance \n B- client's pets, name, type and date of last visit\n C-change the client's outstanding balance: "); 
      menu = input.next().charAt(0); 
      System.out.print("Enter client ID: "); 
      id = input.nextInt(); 
      h = new Human(); 
      if(id == h.getCiD())//if the id entered up top is equal to one of the id's in the txt file then it continues to the menu 
      { 
       p = new Pet(); 
      switch(menu) 
     { case 'A': 
      System.out.println("client name: " + h.getFirstName() + "outstanding balance: " + h.getBalance()); 
      break; 
      case 'B': 
      System.out.println("pet's name: " + p.getName() + "type of pet: " + p.getTanimal() + "date of last visit: " + p.getLastVisit()); 
      break; 
      case 'C': 
      System.out.println("what do you want to change the clients balances to?"); 


     input.close(); 
     } 
    } 
    else// if not then it goes to this If statement saying that the Client does not exist 
    { 
     System.out.println("Client does not exist."); 
    } 
    } 
} 
} 
+0

有一個文件格式的例子嗎?你可能使用'String#split'而不是'StrongTokenizer'獲得更好的運氣。 – MadProgrammer

+0

是的,先生,我應該複製並過去幾次? – Dust

+0

是的,請將它們添加到問題 – MadProgrammer

回答

2

你有許多需要克服的問題...

  • 對於每一行,你需要確定數據的類型的線代表
  • 你的東東d一些方法來跟蹤你已經加載的數據
  • 你需要一些方法來每個寵物與它的主人

第一個可以在許多做關聯(客戶和他們的寵物)方式,假設我們可以改變數據。你可以使第一個標記有意義(human,pet);您可以改用JSON或XML。但讓我們暫時假設,你不能改變格式。

這兩種數據類型之間的關鍵區別在於它們包含的令牌數量,對於人們來說是7,對於寵物來說是5。

while (input.hasNext()) { 
    String text = input.nextLine(); 
    String[] parts = text.split(","); 
    if (parts.length == 7) { 
     // Parse owner 
    } else if (parts.length == 5) { 
     // Parse pet 
    } // else invalid data 

對於第二個問題,你可以使用數組,但你將需要預先知道你需要的元素個數,人與每個人的數量,寵物

奇怪的數足夠了,我只注意到最後一個元素是int,似乎代表了寵物的數量!

Morely,Robert,123 Anywhere Street,15396,4,234.56,2 
            ------------^ 

但這並不能幫助我們的業主。

爲業主,你可以使用某種形式的List和當過您創建一個新Human,您只需將它們添加到List,例如...

List<Human> humans = new ArrayList<>(25); 
//... 
    if (parts.length == 7) { 
     // Parse the properties 
     human = new Human(...); 
     humans.add(human); 
    } else if (parts.length == 5) { 

第三,對於寵物,每個Pet應該與業主直接相關,例如:

Human human = null; 
while (input.hasNext()) { 
    String text = input.nextLine(); 
    String[] parts = text.split(","); 
    if (parts.length == 7) { 
     //... 
    } else if (parts.length == 5) { 
     if (human != null) { 
      // Parse pet properties 
      Pet pet = new Pet(name, type, age, date1, date2); 
      human.add(pet); 
     } else { 
      throw new NullPointerException("Found pet without human"); 
     } 
    } 

好了,這一切的呢,每次我們創建一個Human,我們保留對參考「當前」或「最後」所有者創建。對於我們解析的每條「寵物」行,我們將其添加到所有者。

現在,Human類可以使用數組或List管理寵物,或者將工作,因爲我們知道寵物的預期數量。然後,您將在Human課程中提供獲得者以獲得對寵物的參考。

由於外的上下文代碼可能難以閱讀,這是你也許可以做一個例子...

Scanner input = new Scanner(new File("data.txt")); 
List<Human> humans = new ArrayList<>(25); 
Human human = null; 
while (input.hasNext()) { 
    String text = input.nextLine(); 
    String[] parts = text.split(","); 
    if (parts.length == 7) { 
     String firstName = parts[0]; 
     String lastName = parts[1]; 
     String address = parts[2]; 
     int cid = Integer.parseInt(parts[3]); 
     int vists = Integer.parseInt(parts[4]); 
     double balance = Double.parseDouble(parts[5]); 
     int other = Integer.parseInt(parts[6]); 
     human = new Human(firstName, lastName, address, cid, vists, balance, other); 
     humans.add(human); 
    } else if (parts.length == 5) { 
     if (human != null) { 
      String name = parts[0]; 
      String type = parts[1]; 
      int age = Integer.parseInt(parts[2]); 
      String date1 = parts[3]; 
      String date2 = parts[4]; 
      Pet pet = new Pet(name, type, age, date1, date2); 
      human.add(pet); 
     } else { 
      throw new NullPointerException("Found pet without human"); 
     } 
    } 
} 
0

怎麼樣使用split()功能,而不是使用StringTokenizer

說,你可以改變你的第一while循環象下面這樣:

while (input.hasNext()) { 
// StringTokenizer st = new StringTokenizer(input.nextLine(), ","); 
    String[] tokens = input.nextLine().split(","); 
    if (tokens.length == 7) { 
     h = new Human(); 
     h.setLastName(tokens[0]); 
     h.setFirstName(tokens[1]); 
     h.setAddress(tokens[2]); 
     h.setCiD(Integer.parseInt(tokens[3])); 
     h.setVisits(Integer.parseInt(tokens[4])); 
     h.setBalance(Double.parseDouble(tokens[5])); 
    } else { 
     p = new Pet(tokens[0], tokens[1], Integer.parseInt(tokens[2]), tokens[3], tokens[4]); 
    } 
} 

且其用於跟蹤寵物屬於哪個人的,可以追加Pet類型的ArrayList中Human類象下面這樣:

ArrayList<Pet> pets = new ArrayList<>(); 

,說你有在主函數命名humansHuman類型的另一個ArrayList。所以,你可以在if塊像追加:

humans.add(h); 

,並在else部分,你可以追加在else塊:

humans.get(humans.size()-1).pets.add(p); 
+0

每個'人類'有7個標記:P - 那麼你如何1跟蹤你創建的所有人類並將他們的寵物與他們聯繫起來? – MadProgrammer

+0

@MadProgrammer哦!錯字。我認爲他可以通過在'Human'類中添加一個arrayList來處理它。不管怎樣,謝謝。 – manetsus

0

你可以嘗試這樣的事情 - 填充地圖然後使用它您可以根據您的要求分配值。

public void differentiate(){ 
    try { 
     Scanner scan=new Scanner(new BufferedReader(new FileReader("//your filepath"))); 
      Map<String,List<String>> map=new HashMap<String, List<String>>(); 
      while(scan.hasNextLine()){ 
      List<String> petList=new ArrayList<String>(); 
      String s=scan.nextLine(); 
      String str[]=s.split(","); 
      String name=str[1]+" "+str[0]; 
      int petCount=Integer.parseInt(str[str.length-1]); 
       for(int i=1;i<=petCount;i++){ 
       String petString=scan.nextLine(); 
       petList.add(petString); 
       } 
       map.put(name, petList); 
      } 
      Set<String> set=map.keySet(); 
      for(String str:set){ 
       System.out.println(str+" has "+map.get(str)+" pets"); 
      } 
     } 
     catch (FileNotFoundException e) { 
     System.out.println(e.getMessage()); 
    } 

}