/* kerho.cpp */ /****************************************************************************/ /* ** K E R H O . C P P ** ** Kerho-luokan toteutus ** ** Tekij„t: Vesa Lappalainen ** Ohjelmointikurssi 1991 ** Tehty: 20.12.1991 ** Muutettu: 09.12.1995 ** Mit„ muutettu: Muutettu C++ luokaksi ** Muutettu: 10.12.1995 ** Mit„ muutettu: + Laitettu tiedoston lukeminen ja kirjoittaminen ** toimivaksi (ks. metodit lue_tiedostosta ja talleta) ** + J„senen lis„ys kasvattaa taulukon kokoa, mik„li ** tila loppuu (ks. lisaa) ** ** Public-metodeja: ** ================ ** ** Metodit palauttavat yleens„ virheen merkkijonona, joka voidaan ** suoraan tulostaa. Jos virhett„ ei tapahdu, palautetaan NULL. ** ** cKerho(int koko=0) ** - kerhon luominen, jos koko = 0, ei luoda j„sentaulukkoa ** ** ~cKerho() ** - kerhon h„vitt„minen, jos kerhoa ei ole talletettu, talletetaan ** viimeist„„n nyt (mahd. virheilmoitus harakoille) ** ** const char *lisaa(const cJasen &jasen); ** - lis„t„„n uusi j„sen. J„senest„ tehd„„n kopio. Jos tila loppuu, ** yritet„„n kasvattaa tilaa. ** ** const cJasen &anna(int i) const ** - otetaan kerhosta i:s j„sen. Jos i v„„rin, otetaan 0:s j„sen. ** Kerholaisia voidaan muuttaa, kun otetaan j„senest„ kopio ** anna-metodilla, muutetaan kopion tietoja ja laitetaan takaisin ** korvaa-metodilla: ** cJasen jasen(kerho.anna(i)); ** - muuta jasenta ** kerho.korvaa(i,jasen); ** ** const char *luo(const string &tied,const string &nimi, ** - luo j„senist”n uutta kerhoa varten, mahd. vanha talletetaan ** ** const char *lue(const string &tied); ** - luetaan uusi j„senist”, mahd. vanha talletetaan ** ** const char *talleta(const string &tied=""); ** - talletetaan j„sensist„. Jos tied=="", k„ytet„„n luettaessa ** annettua nimi„. ** ** const string &Kerhon_nimi() const ** - palauttaa kerhon koko nimen. ** ** int jasenlkm() const ** - palauttaa kerhon j„senm„„r„n ** ** const string &Tiedoston_nimi() const ** - paluttaa viimeksi k„ytetyn tiedoston nimen ** ** int Muutettu() const ** - palauttaa 1, mik„li kerhoa on muutettu talletusten j„lkeen ja ** 0 muuten. ** ** --------------------------------------------------------------------------- ** ** Tietorakenne on seuraava: ** ========================= ** ** ** cKerho cJasen ** ------ ** | | ------ ** | | | | ** | 7 | max |---->| | ** | 3 | jasenet | | | ------ ** | o--+------>|-----| | ------ | | ** ------ | o--+-----| | | ** |-----| |----->| | ** | o--+------------| ------ ------ ** |-----| | | ** | o--+--------------------------->| | ** |-----| | | ** | o--+--? ------ ** |-----| ** | o--+--? ** |-----| ** | o--+--? ** |-----| ** | o--+--? ** |-----| ** ** ** Kerho ei tied„ j„seniens„ ominaisuuksia. ** Kerho pit„„ huolta siit„, onko kerho muuttunut, eli tarvitseeko se ** talletusta vaiko ei. ** Tiedoston muoto, ks. lue_tiedostosta - metodi ** */ #include #include #include "mjonotpp.h" #include "kerho.h" //============================================================================ // Makrot: //============================================================================ //---------------------------------------------------------------------------- // Makro, jolla tutkitaan palauttiko kutsu v virheen vai ei ja jos // palautti, niin poistutaan aliohjelmasta palauttaen sama virhe. #define IF_ERR_RETURN(v) { const char *virhe=(v); if ( virhe ) return virhe; } //============================================================================ // Virheilmoitukset: //============================================================================ static const char *EI_VOI_LUODA = "J„senist”lle ei saada varattua tilaa" " muistista!"; static const char *LIIKAA_JASENIA = "Liikaa j„seni„, ei voi lis„t„!"; static const char *EI_SAA_JASENTA = "Ei saada tilaa uudelle j„senelle!"; static const char *EI_NIMEA = "Ei kerhon nime„ tiedostossa!"; static const char *EI_MAXKOKOA = "Ei maksimikokoa tiedoston alussa!"; static const char *TIED_EI_AUKEA = "Tiedosto ei aukea!"; static const char *OTS_EI_KIRJ = "Otsikkotietoja ei voi kirjoittaa!"; static const char *JASEN_EI_KIRJ = "J„sent„ ei voi kirjoittaa!"; //============================================================================ // Private -metodeja: //============================================================================ //---------------------------------------------------------------------------- void cKerho::poista_jasentaulukko() { if ( max_jasenia > 0 ) free(jasenet); max_jasenia = 0; } //---------------------------------------------------------------------------- void cKerho::poista_jasenet() { for (int i=0; i= max_jasenia ) IF_ERR_RETURN(kasvata_kokoa()); cJasen *uusi_jasen = new cJasen(jasen); if ( uusi_jasen == NULL ) return EI_SAA_JASENTA; jasenet[jasenia] = uusi_jasen; jasenia++; muutettu = 1; return NULL; } //---------------------------------------------------------------------------- const char *cKerho::luo_jasentaulukko(int koko) /* ** Luodaan j„sentaulukko valitun kokoiseksi. Jos j„sentaulukko on ennest„„n ** on siell„ on se parasta poistaa. ** Luomisessa k„ytet„„n malloc-funktiota, jotta koon muuttaminen on ** jatkossa helpompaa realloc-funktiolla. (ks. lisaa-metodi). ----------------------------------------------------------------------------*/ { poista_jasenisto(); if ( koko <= 0 ) return NULL; jasenet = (cJasen **)malloc( koko * (sizeof(cJasen *)) ); jasenia = 0; max_jasenia = 0; if ( jasenet == NULL ) return EI_VOI_LUODA; max_jasenia = koko; return NULL; } //---------------------------------------------------------------------------- const char *cKerho::luo(const string &tied,const string &nimi,int max_jas) /* ** Luodaan uusi kerho valitulla tiedoston nimell„ ja kerhon nimell„. ** Taulukon yl„rajaksi luodaan max_jas. ----------------------------------------------------------------------------*/ { IF_ERR_RETURN(luo_jasentaulukko(max_jas)); tiedoston_nimi = tied; kerhon_nimi = nimi; muutettu = 1; return NULL; } //---------------------------------------------------------------------------- const char *cKerho::lue_tiedostosta(const string &tied) { /* ** Luetaan tiedostosta kerhon tiedot. ** ** Metodit olettavat tiedoston olevan seuraavaa muotoa: ** **Kelmien kerho ry **50 **; Kenttien j„rjestys tiedostossa on seuraava: **; sukunimi etunimet|sotu |katuosoite |postinumero|postiosoite|koti... **Ankka Aku |010245-123U|Ankkakuja 6 |12345 |ANKKALINNA |12-1... **Susi Sepe |020347-123T| |12555 |Per„mets„ | ... **Ponteva Veli |030455-3333| |12555 |Per„mets„ | ... ** ** ** Tiedoston 3. rivilt„ alkaen olevat kommenttirivit (merkitty ;) unohdetaan. ** ** Taulukon yl„rajaksi luodaan tiedosta 2. rivilt„ luettu max_koko. ----------------------------------------------------------------------------*/ ifstream f(tied.c_str()); if ( !f ) return TIED_EI_AUKEA; string nimi; lue_rivi(f,nimi); if ( !f ) return EI_NIMEA; int max_koko; lue_rivi(f,max_koko); if ( !f ) return EI_MAXKOKOA; IF_ERR_RETURN(luo_jasentaulukko(max_koko)); tiedoston_nimi = tied; kerhon_nimi = nimi; char rivi[400]; cJasen jasen; while ( f ) { lue_rivi(f,rivi,sizeof(rivi)); if ( rivi[0] == 0 || rivi[0] == ';' ) continue; jasen.alusta(rivi); // f >> jasen; // vaatisi kunkin rivin olemisen t„ydellisen„, muuten OK! IF_ERR_RETURN(lisaa(jasen)); } muutettu = 0; return NULL; } //---------------------------------------------------------------------------- const char *cKerho::talleta(const string &tied) { if ( !muutettu ) return NULL; string tiedosto(tied); if ( tied == "" ) tiedosto = tiedoston_nimi; ofstream f(tiedosto.c_str()); if ( !f ) return TIED_EI_AUKEA; f << kerhon_nimi << endl; f << max_jasenia << endl; if ( !f ) return OTS_EI_KIRJ; for (int i=0; i