Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

17.6 Esimerkki tiedoston lukemisesta

Seuraavaksi kirjoitamme ohjelman, jossa tulee esiin varsin yleinen ongelma: tietueen etsiminen joukosta. Kirjoitamme edellisiä esimerkkejä vastaavan ohjelman, jossa tavallisen tulostuksen sijasta tulostetaan kunkin tuoteluokan yhteistilanne.

tiedosto\LueTRek.java - esimerkki tiedoston lukemisesta

	import java.io.*;
	import fi.jyu.mit.ohj2.*;
	/**
	 * Ohjelma lukee tiedostoa tuotteet.dat, joka on muotoa:
	 * <pre>
	 *   Volvo |  12300 | 1
	 *   Audi  |  55700 | 2
	 *   Saab  |   1500 | 4
	 *   Volvo | 123400 | 1
	 * </pre>
	 * Ohjelma tulostaa kuhunkin tuoteluokkaan kuuluvien tuotteiden
	 * yhteishinnat ja kappalemäärät sekä koko varaston yhteishinnan
	 * ja kappalemäärän.  Eli em. tiedostosta tulostetaan:
	 * <pre>
	 * -------------------------------------------
	 * Volvo                 135700    2
	 * Audi                  111400    2
	 * Saab                    6000    4
	 * -------------------------------------------
	 * Yhteensä              253100    8
	 * -------------------------------------------
	 *</pre>
	 * @author Vesa Lappalainen
	 * @version 1.0, 09.03.2003
	 */
	public class LueTRek {
	
	  /****************************************************************************/
	  /**
	   * Luokka yhden tuotteen tiedoille.
	   */
	  static public class Tuote {
	    private String nimike = "";
	    private double hinta = 0.0;
	    private int kpl = 0;
	
	    public Tuote() {}
	    public Tuote(String rivi) {
	      try {
	        parse(rivi);
	      } catch (NumberFormatException ex) {
	      }
	    }
	
	    public void parse(String s) throws NumberFormatException {
	      StringBuffer sb = new StringBuffer(s);
	      nimike = Mjonot.erotaEx(sb,'|',nimike);
	      hinta  = Mjonot.erotaEx(sb,'|',hinta);
	      kpl    = Mjonot.erotaEx(sb,'|',kpl);
	    }
	
	    public String toPrintString() {
	      return Mjonot.fmt(nimike,-20) + " " + Mjonot.fmt(hinta,7,0) +
	             Mjonot.fmt(kpl,4);
	    }
	
	    public void ynnaa(Tuote tuote) {
	      hinta += tuote.hinta * tuote.kpl;
	      kpl   += tuote.kpl;
	    }
	
	    public String getNimike() { return nimike; }
	    public void setNimike(String nimike) { this.nimike = nimike; }
	
	  }
	
	  /****************************************************************************/
	  /**
	   * Luokka joka säilyttää kunkin ero tuotteen yhteissumman ja lukumäär'n
	   * sekä kaikkien tuotteiden yhteissumman ja lukumäärän
	   */
	  static public class Tuotteet {
	    private String nimi = "";
	    private int lkm;
	    private Tuote alkiot[];
	    private Tuote yhteensa = new Tuote("Yhteensä");
	
	    public Tuotteet(String nimi) {
	      this.nimi = nimi;
	      alkiot = new Tuote[10];
	    }
	
	    public int etsi(String tnimi) {
	      for (int i=0; i<lkm; i++)
	        if ( alkiot[i].getNimike().equalsIgnoreCase(tnimi) ) return i;
	      return -1;
	    }
	
	    public int lisaa(String tnimi) {
	      if ( alkiot.length <= lkm ) return -1;
	      alkiot[lkm] = new Tuote(tnimi);
	      return lkm++;
	    }
	
	    public boolean ynnaa(Tuote tuote) {
	      if ( tuote.getNimike().equals("") ) return false;
	      int i = etsi(tuote.getNimike());
	      if ( i < 0 ) i = lisaa(tuote.getNimike());
	      if ( i < 0 ) return false;
	
	      alkiot[i].ynnaa(tuote);
	      yhteensa.ynnaa(tuote);
	      return true;
	    }
	
	
	    public boolean lue() {
	      BufferedReader fi = Tiedosto.avaa_lukemista_varten("tuotteet.dat");
	      if ( fi == null ) return false;
	
	      try {
	        String rivi;  Tuote tuote = new Tuote();
	        while ( ( rivi = fi.readLine() ) != null ) {
	          try {
	            tuote.parse(rivi);
	            ynnaa(tuote);
	          } catch (NumberFormatException ex) {
	            System.err.println("Rivillä jotakin pielessä " + rivi + "  " +
	                                ex.getMessage());
	            continue;
	          }
	        }
	      } catch (IOException ex) {
	        System.err.println("Vikaa tiedostoa luettaessa");
	      } finally {
	        try {
	          fi.close();
	        } catch (IOException ex) {
	          System.err.println("Ongelmia tiedoston sulkemisessa");
	        }
	      }
	
	      return true;
	    }
	
	    public void tulosta(OutputStream os) {
	      PrintStream out = Tiedosto.getPrintStream(os);
	
	      out.println(); out.println(); out.println();
	      out.println("-------------------------------------------");
	
	      for (int i=0; i<lkm; i++)
	        out.println(alkiot[i].toPrintString());
	
	      out.println("-------------------------------------------");
	      out.println(yhteensa.toPrintString());
	      out.println("-------------------------------------------");
	      out.println(); System.out.println(); System.out.println();
	    }
	
	  }
	
	  /****************************************************************************/
	  public static void main(String[] args)  {
	    Tuotteet varasto = new Tuotteet("tuotteet.dat");
	    if ( !varasto.lue() ) {
	      System.err.println("Tuotteita ei saada luetuksi");
	      return;
	    }
	    varasto.tulosta(System.out);
	  }
	}

Tehtävä 17.4 Tietorakenne

Piirrä kuva Tuotteet - luokan tietorakenteesta.

Tehtävä 17.5 Perintä

Miten voisit perinnän avulla saada tiedoston luerek.cpp luokasta Tuote tiedoston LueTRek.java vastaavan luokan (tietysti eri nimelle, esim. RekTuote). Mitä muutoksia olisi hyvä tehdä alkuperäisessä Tuote- luokassa.

Tehtävä 17.6 Tunnistenumero

Lisää LueTRek.java- ohjelmaan tunnistenumeron käsittely mahdollista tulevaa relaatiokäyttöä varten.

Tehtävä 17.7 Mittakaava

Kirjoita mittakaavaohjelma, jossa on vakiotaulukko
yks
mm
mm
cm
dm
m
inch
1.0
10.0
100.0
1000.0
25.4
ja jonka toiminta näyttäisi seuraavalta:
	...
	Mittakaava ja matka>1:10000 10 cm[RET]
	Matka maastossa on 1.00 km.
	Mittakaava ja matka>1:200000 20[RET]
	Matka maastossa on 4.00 km.
	Mittakaava ja matka>loppu[RET]
	Kiitos! 
Muuta ohjelmaa siten, että yksiköiden muunnostaulukko luetaan ohjelman aluksi tiedostosta muunnos.dat.
Muuta ohjelmaa vielä siten, että mikäli mittakaava jätetään antamatta, käytetään edellisellä kerralla annettua mittakaavaa ja ensimmäinen luku onkin matka.
	...
	Mittakaava ja matka>1:10000 10 cm[RET]
	Matka maastossa on 1.00 km.
	Mittakaava ja matka>0.20 dm[RET]
	Matka maastossa on 0.20 km.
	Mittakaava ja matka>loppu[RET]
	Kiitos! 


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys