previous next Up Title Contents Index

17.8 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\tuoterek.cpp - esimerkki tiedoston lukemisesta C-funktiolla

	// tuoterek.cpp 
	/*
	  Ohjelma lukee tiedostoa TUOTTEET.DAT, joka on muotoa:
	
	    Volvo |  12300 | 1
	    Audi  |  55700 | 2
	    Saab  |   1500 | 4
	    Volvo | 123400 | 1
	
	  Ohjelma tulostaa kuhunkin tuoteluokkaan kuuluvien tuotteiden
	  yhteishinnat ja kappalemäärät sekä koko varaston yhteishinnan
	  ja kappalemäärän.  Eli em. tiedostosta tulostetaan:
	
	-------------------------------------------
	Volvo                 135700    2
	Audi                  111400    2
	Saab                    6000    4
	-------------------------------------------
	Yhteensä              253100    8
	-------------------------------------------
	
	  Vesa Lappalainen 15.3.1996
	  Projektiin: tuoterek.cpp,ALI\mjonot.c
	*/
	
	#include <iostream.h>
	#include <iomanip.h>
	#include <strstream.h>
	#include <fstream.h>
	#include <stdio.h>
	#include <string.h>
	#include <string>
	using namespace std;
	#include <mjonot.h>
	#include <mjonotpp.h>
	
	//---------------------------------------------------------------------------
	class cTuote {
	  string nimike;
	  double hinta;
	  int    kpl;
	public:
	  int alusta(const char *n,double h,int k=0) {
	    nimike = n; hinta = h; kpl = k; return 0;
	  }
	  int alusta(const char *rivi) {  // Alustaa jonosta Volvo|4500|3
	    istrstream sstr((char *)rivi);
	    return lue(sstr);
	  }
	  int alusta()                            { return alusta("",0,0);           }
	  cTuote()                                { alusta();                        }
	  cTuote(const char *rivi)                { alusta(rivi);                    }
	  int lue(istream &is) {...}
	  ostream &tulosta(ostream &os) const { ... }
	
	  void ynnaa(const cTuote &tuote) {
	    hinta += tuote.hinta * tuote.kpl;
	    kpl   += tuote.kpl;
	  }
	  cTuote &operator+=(const cTuote &tuote) { ynnaa(tuote); return *this;      }
	
	  const string &Nimike() const            { return nimike;                   }
	};
	
	
	ostream &operator<<(ostream &os,const cTuote &tuote)
	  { return tuote.tulosta(os); }
	istream &operator>>(istream &is,cTuote &tuote) { tuote.lue(is); return is; }
	
	
	//---------------------------------------------------------------------------
	const int MAX_TUOTTEITA = 10;
	
	class cTuotteet {
	  string nimi;
	  int    tuotteita;
	  cTuote tuotteet[MAX_TUOTTEITA];
	  cTuote yhteensa;
	public:
	  cTuotteet(const char *n) : nimi(n), yhteensa("Yhteensä") { tuotteita = 0;  }
	  ostream &tulosta(ostream &os) const;
	  int etsi(const string &tnimi) const;
	  int lisaa(const string &tnimi);
	  int ynnaa(const cTuote &tuote);
	  int lue(const char *s=NULL);
	};
	
	int cTuotteet::etsi(const string &tnimi) const
	{
	  int i;
	  for (i=0; i<tuotteita; i++)
	    if ( tuotteet[i].Nimike() == tnimi ) return i;
	  return -1;
	}
	
	int cTuotteet::lisaa(const string &tnimi)
	{
	  if ( tuotteita >= MAX_TUOTTEITA ) return -1;
	  tuotteet[tuotteita].alusta(tnimi.c_str(),0.0,0);
	  return tuotteita++;
	}
	
	int cTuotteet::ynnaa(const cTuote &tuote)
	{
	  if ( tuote.Nimike() == "" ) return 1;
	  int i = etsi(tuote.Nimike());
	  if ( i < 0 ) i = lisaa(tuote.Nimike());
	  if ( i < 0 ) return 1;
	
	  tuotteet[i] += tuote;
	  yhteensa    += tuote;
	
	  return 0;
	}
	
	int cTuotteet::lue(const char *s)
	{
	  char rivi[80];
	
	  if ( s ) nimi = s;
	  ifstream f(nimi.c_str());  if ( !f ) return 1;
	
	  while ( f.getline(N_S(rivi)) ) {
	    cTuote tuote(rivi);
	    if ( ynnaa(tuote) )
	      cout << "Rivillä \"" << rivi << "\" jotain pielessä!" << endl;
	  }
	  return 0;
	}
	
	
	ostream &cTuotteet::tulosta(ostream &os) const
	{
	  int i;
	  os << "\n\n\n";
	  os << "-------------------------------------------\n";
	  for (i=0; i<tuotteita; i++)
	    os << tuotteet[i] << "\n";
	  os << "-------------------------------------------\n";
	  os << yhteensa << "\n";
	  os << "-------------------------------------------\n";
	  os << "\n\n" << endl;
	  return os;
	}
	
	
	int main(void)
	{
	  cTuotteet varasto("tuotteet.dat");
	
	  if ( varasto.lue() ) {
	    cout << "Tuotteita ei saada luetuksi!" << endl;;
	    return 1;
	  }
	
	  varasto.tulosta(cout);
	
	  return 0;
	}

Tehtävä 17.158 Tietorakenne

Piirrä kuva cTuotteet - luokan tietorakenteesta.

Tehtävä 17.159 Perintä

Miten voisit perinnän avulla saada tiedoston tuote_pao.cpp luokasta cTuote tiedoston tuoterek.cpp vastaavan luokan (tietysti eri nimelle, esim. cRekTuote). Mitä muutoksia olisi hyvä tehdä alkuperäisessä cTuote- luokassa.

Tehtävä 17.160 Tunnistenumero

Lisää tuoterek.cpp- ohjelmaan tunnistenumeron käsittely mahdollista tulevaa relaatiokäyttöä varten.

Tehtävä 17.161 Mittakaava

Kirjoita mittakaavaohjelma, jossa on vakiotaulukko
y
ks

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! 


previous next Up Title Contents Index