/* kassa3.cpp - vastaukset kassa2.cpp:n tehtäviin. Ongelma: Ohjelma toimii alkeellisena kassakoneena JO-112: Kirjoita C++-ohjelma, joka matkii yksinkertaisen kassakoneen toimintaa: Ensin kaikista myyntiartikkeleista luetaan näppäimistöltä (korvataa tiedostosta) koodi, nimi ja yksikköhinta, jotka tallennetaan taulukoihin. Sitten kustakin myytävästä tuotteesta luetaan koodi ja kappalemäärä. Lopuksi tulostetaan näytölle kuitti, josta näkyy kunkin tuotteen kokonaishinta sekä kaikkien ostosten yhteishinta. Syöttö ja tulostus tehdään omissa funktioissaan. Samalla suorituskerralla voidaan palvella useita asiakkaita. Tekijä: Vesa Lappalainen 28.2.2002 Projektiin: tämä, mjonot.c (Huom! Muista päivittää \kurssit\cpp\ali!) Tehtäviä: ========= 1) Muutokset: 1.3.2002/vl + tulostuksen muotoilu cStreamPre-luokan avulla + alusta vaihdettu nimelle setAsString + lisätty cKassakone + lisätty cKayttoliittyma + cTuotteet::tyhjenna + cTuotteet::etsi Suunnitelma: ============ Olen armottoman hieno kassakone... Anna koodi ja määrä >maito 3 l[ret] Anna koodi ja määrä >voi 2 kg[ret] Anna koodi ja määrä >[ret] Kuitti: Maito 3 1.98 Euroa Voi 2 10.00 Euroa ======================= 11.98 Euroa Päivämäärä 28.2.2002 Anna koodi ja määrä >lopeta[ret] Moikka!!! ================================================ hinnat.txt: Maito| 0.666 | 100 Voi | 5.00 | 20 Laku | 0.1 | 1000 Luokat: cTuote - osaa käsitellä rivin joka on muotoa : Maito| 0.666 | 100 - osaa tulostaa itsensä muodossa: Maito 3 1.98 Euroa - oletko "maito" cTuotteet - hoitaa että on monta tuotetta - etsiä tuote cKassakone - huolehtii kuiteista ja hinnastosta - osaa tyhjentää kuitin cKayttoliittyma - huolehtii käyttäjän tempuista Kuva: |------| cKayttoliittyma | | | | | o | |--+---| cKassakone | v |-----------------------------------------------------| | hinnat Kuitti | | cTuotteet cTuotteet | | |------| |------| | | | 4 | | 4 | | | | 3 | | 2 | | | | o | | o | | | |--+---| |--+---| | |-----|--------------------------------------|--------| | | | | | | | | v v |-------| |-------| |-------| |-------| 0 | o---+---------->| Maito | 0 | o---+---------->| Maito | |-------| | 0.66 | |-------| | 1.98 | 1 | o---+-------| | 100 | 1 | o---+-------| | 3 | |-------| | |-------| |-------| | |-------| 2 | o---+---| | 2 | | | |-------| | | |-------| |-------| | |-------| 3 | | | --->| Voi | 3 | | --->| Voi | |-------| | | 5.00 | |-------| | 10.00 | | | 20 | | 2 | | |-------| |-------| | | |-------| ------->| Laku | | 0.10 | | 1000 | |-------| */ #include #include #include #include #include #include "mjonotpp.h" #include "dosout.h" #include "streampr.h" // BC 3.1 käyttäjät korvatkaa seuraava 1 nollalla #if 1 using std::string; using std::ostream; using std::ios; using std::setw; using std::nothrow; using std::cin; using std::endl; using std::ofstream; #else using namespace std; #endif class cTuote { string koodi; double hinta; double maara; public: cTuote() : koodi(), hinta(0), maara(0) {} cTuote(string ikoodi,double ihinta=0.0,double imaara=0.0) : koodi(ikoodi), hinta(ihinta), maara(imaara) {} void tulosta(ostream &os) const { cStreamPre pre(os,2,ios::left); os << setw(10) << koodi << " "; os.setf(ios::right); os << setw(8) << maara << " " << setw(8) << hinta << " Euroa\n"; } bool oletko(const string &nimi) const { // if ( nimi == koodi ) return true; // return false; return ( onko_samat(koodi,nimi) == 0 ); } void setAsString(string jono) { koodi = erota(jono,'|'); poista_tyhjat(koodi); luvuksi(erota(jono,'|'),hinta); luvuksi(erota(jono,'|'),maara); } double getHinta() const { return hinta; } void setHinta(double ihinta) { hinta = ihinta; } string getKoodi() const { return koodi; } }; class cTuotteet { int maxlkm; int lkm; cTuote vikatuote; cTuote **tuotteet; public: cTuotteet(int imaxlkm) : maxlkm(0), lkm(0), vikatuote("???") { tuotteet = new(nothrow) cTuote *[imaxlkm]; if ( tuotteet == 0 ) return; maxlkm = imaxlkm; } ~cTuotteet() { tyhjenna(); if ( maxlkm > 0 ) delete [] tuotteet; } int getLkm() const { return lkm; } string lisaa(const cTuote &tuote) { if ( lkm >= maxlkm ) return "Ei mahu!"; try { cTuote *uusi = new cTuote(tuote); tuotteet[lkm] = uusi; lkm++; return ""; } catch ( std::bad_alloc ) { return "Muisti loppu!"; } } string lue_tiedosto(const string &tiednimi) { cTuote tuote; tuote.setAsString("Maito| 0.666 | 100"); lisaa(tuote); tuote.setAsString("Voi | 5.00 | 20"); lisaa(tuote); tuote.setAsString("Laku | 0.1 | 1000"); lisaa(tuote); return ""; } const cTuote &anna(int i) const { if ( i < 0 || getLkm() <= i ) return vikatuote; return *tuotteet[i]; } void tyhjenna(); int etsi(const string &tunnus); }; void cTuotteet::tyhjenna() { for (int i=0; ioletko(tunnus) ) return i; return -1; } class cKassakone { cTuotteet hinnasto; cTuotteet kuitti; public: cKassakone() : hinnasto(10), kuitti(10) { } string lue_tiedosto(const string &tiednimi) { return hinnasto.lue_tiedosto(tiednimi); } void tyhjenna_kuitti() { kuitti.tyhjenna(); } void tulosta_kuitti(ostream &os) const; string lisaa_rivi(string rivi) { // Ottaa syötteenään rivin muotoa: maito 3 l // Etsii riviä vastaavan tuotteen. Jos ei löydy, palauttaa tiedon. // Sitten löytyneen tuoteet perusteella lisää kuittiin rivin. double maara; string nimi = erota(rivi); int i = hinnasto.etsi(nimi+"*"); if ( i < 0 ) return "Ei tunneta tuotetta '" + nimi + "'"; const cTuote &tuote=hinnasto.anna(i); luvuksi(erota(rivi),maara,1.0); cTuote kuittirivi(tuote.getKoodi(),tuote.getHinta()*maara,maara); return kuitti.lisaa(kuittirivi); } }; void cKassakone::tulosta_kuitti(ostream &os) const { if ( kuitti.getLkm() == 0 ) return; double summa=0; os << "\n\n"; os << "===========================================\n"; for (int i = 0; i < kuitti.getLkm(); i++) { const cTuote &kuitinrivi = kuitti.anna(i); kuitinrivi.tulosta(os); summa += kuitinrivi.getHinta(); } cStreamPre pre(os,2,ios::right); os << "===========================================\n"; os << setw(10+1+8+1+8) << summa << " Euroa\n"; os << "\n\n"; } class cKayttoliittyma { cKassakone *kassakone; public: cKayttoliittyma(cKassakone *kassa) : kassakone(kassa) { } int alku() { string virhe = kassakone->lue_tiedosto("hinnat.txt"); if ( virhe != "" ) { cout << virhe << endl; return 1; } cout << "Olen armottoman hieno kassakone käyttö loppuu kun\n"; cout << "kirjoitat: lopeta" << endl; return 0; } int aja(); int lopetus() const { cout << "Moikka!!!\n"; return 0; } void tulosta_kuitti() const { kassakone->tulosta_kuitti(cout); std::ofstream of("kuitti.txt",ios::app); if ( !of ) { cout << "Kuittia ei voi kirjoittaa\n"; return; } kassakone->tulosta_kuitti(of); } }; int cKayttoliittyma::aja() { string jono; while ( 1 ) { cout << "Anna koodi ja määrä >"; getline(cin,jono); if ( jono == "lopeta" ) { tulosta_kuitti(); break; } if ( jono == "" ) { tulosta_kuitti(); kassakone->tyhjenna_kuitti(); continue; } string virhe = kassakone->lisaa_rivi(jono); if ( virhe != "" ) cout << virhe << "\n"; } return 0; } int main(void) { //#define TUOTETESTI #ifdef TUOTETESTI cTuote tuote("Maito",1.98,3); tuote.tulosta(cout); cTuote tuote2("Voi",10,2); tuote2.tulosta(cout); if ( tuote.oletko("maito") ) cout << "on maito\n"; tuote.setAsString("Laku|0.1|1000"); tuote.tulosta(cout); #endif //#define TUOTEETTESTI #ifdef TUOTTEETTESTI cTuotteet hinnasto(4); hinnasto.lue_tiedosto("hinnat.txt"); for (int i=0; i