/****************************************************************************/ /* ** K E R H O R A K . C ** ** Kerhon rakenteeseen oleellisesti liittyvi„ aliohjelmia ** ** Aliohjelmat: ** mallirivi - tekee mallirivin tallettamista varten ** kentan_tyyppi - palauttaa kent„n tyypin ** kentan_osoite - palauttaa kent„n osoitteen ** kentan_koko - palauttaa kent„n koon tavuina ** kentta_jonoksi - palauttaa valitun kent„n merkkijonona ** jono_kentaksi - muuttaa merkkijonon kent„ksi ** tulosta_jasen - tulostaa j„senen valittuun tiedostoon ** poista_NULL - poistaa osoitintaulukosta NULL-osoittimet ** tulosta_kenttalista - tulostaa valittavaksi kaikki j„sentietueen ** kent„t ** alusta_jasen - alustaa j„senen kent„t„ tyhjiksi ** lisaa_jasen - lis„„ uuden j„senen rakenteeseen ** luo_jasentaulukko - luo j„senosoitintaulukon ** kysy_kentta - kysyy j„senen valitun kent„n tiedot ** kysy_jasenen_tiedot - kysyy j„senen kaikkien kenttien tiedot ** kysy_haku - kysyy yhden hakukent„n arvon ** kysy_hakutiedot - kysyy koko hakutaulukon tiedot ** poista_jasen - varmistaa ja poistaa valitun j„senen ** ** ** ** Yleinen tietorakenne on seuraava: ** ** ** Kerho_tyyppi Haku_tyyppi Jasen_tyyppi ** ------ ------- ** | | | | ** | 7 | |--->| | ** | 3 | | | | ** | | | ------- ------ ** | | | | | ** | o--+----| |---->| | ** | | jasenet | | | ------ ** | o--+------>|-----| | ------ | | ** ------ | o--+-----| | | ** |-----| |----->| | ** | o--+------------| ------ ------ ** |-----| | | ** | o--+--------------------------->| | ** |-----| | | ** | o--+--? ------ ** |-----| ** | o--+--? ** |-----| ** | o--+--? ** |-----| ** | o--+--? ** |-----| ** ** ** ** Tekij„t: Vesa Lappalainen ** Ohjelmointikurssi 1991 ** Tehty: 20.12.1991 ** Muutettu: 21.12.1991 ** Mit„ muutettu: lis„tty kysy_jasenen_tiedot ** Muutettu: 21.12.1991/vl ** Mit„ muutettu Tietojen oikeellisuustarkistukset ** kysy_jasenen_tiedot 2 uutta parametria ** Muutettu: 24.12.1991/vl ** Mit„ muutettu: Lis„tty etsimisess„ ja selailussa tarvittavia osia. ** Muutettu: 25.12.1991/vl ** Mit„ muutettu: Kentt„taulukkoon perustuva rakenne. ** ** */ #include #include #include #include #include "mjonot.h" #include "kerho.h" #define OLET_ALKU 19 /* Oletuksen alkusarake */ #define VAKANEN 33 /* V„k„sen alkusarake */ #define K_A(nimi) sizeof(((Jasen_tyyppi *)0)->nimi),\ offsetof(Jasen_tyyppi,nimi) /* ** K_A(nimi) ** Makro muuttaa Jasentyyppisen tietueen kent„n nimen ** kent„n kooksi ja alkupaikaksi tietueen alusta lukien. */ /* ** Taulukko, johon on ker„tty 'intiimit' tiedot kustakin Jasentietueen ** kent„st„. T„m„n taulukon avulla tietueen kaikkia kentti„ pystyt„„n ** sitten k„ytt„m„„n silmukassa: */ static Kentta_tyyppi KENTAT[] = { {"J„senen nimi" ,"nimi" ,K_A(nimi) ,1,19,Tjono ,"%s",t_nimi}, {"Sotu" ,"sotu" ,K_A(sotu) ,1,11,Tsotu ,"%s",t_sotu}, {"Katuosoite" ,"katuosoite" ,K_A(katuosoite) ,0,15,Tjono ,"%s",t_katu}, {"Postinumero" ,"postinumero" ,K_A(postinumero) ,0,05,Tjono ,"%s",t_numeerinen}, {"Postiosoite" ,"postiosoite" ,K_A(postiosoite) ,0,15,Tjono ,"%s",t_isoksi}, {"Kotipuhelin" ,"kotipuhelin" ,K_A(kotipuhelin) ,0,11,Tjono ,"%s",t_puh}, {"Ty”puhelin" ,"ty”puhelin" ,K_A(tyopuhelin) ,1,11,Tjono ,"%s",t_puh}, {"Autopuhelin" ,"autopuhelin" ,K_A(autopuhelin) ,1,11,Tjono ,"%s",t_puh}, {"Liittymisvuosi" ,"liittymisvuosi",K_A(liittymisvuosi),0,04,Tint ,"%d",t_vuosi_1900}, {"J„senmaksu mk" ,"j„senmaksu" ,K_A(jmaksu) ,0,06,Tdouble,"%6.2lf",t_ok}, {"Maksettu maksu mk","maksettu maksu",K_A(maksu) ,0,06,Tdouble,"%6.2lf",t_ok}, {"Lis„tietoja" ,"lis„tietoja" ,K_A(lisatietoja) ,1,30,Tjono ,"%s",t_ok} }; #undef K_A char KENTTAVALINNAT[50] = "123456789ABCDEFGHIJ ?+-" NAP_KORJ_POISTO NAP_JA_TAI; static char *MALLITULOSTUS[] = { /*Kullekin kent„lle sanotaan tulostusmuoto:*/ " %s" , " %s\n" , /* nimi ja sotu */ " %s" , " %s" , " %s\n" , /* katu, postinro, postios */ " k: %s" , " t: %s" , " a: %s\n" , /* puhelimet */ " Liittynyt %s." , " J„senmaksu %s mk." , " Maksettu %s mk\n" , /* Liittymisvuosi ja maksut */ " %s\n" }; /****************************************************************************/ char /* = "" mik„li tilaa ei saada varattua. */ *mallirivi(void) /* = Talletuksessa k„ytett„v„ mallirivi. */ /* ** Funktiolla luodaan tilaa mallirivi„ varten ja luodaan mallirivi, ** joka on muotoa ** ;nimi |sotu |katuosoite |.... ** ** Globaalit: KENTAT ** Algoritmi: Lis„t„„n KENTAT taulukosta aina seuraava kent„n nimi ** ja laitetaan | kent„n mallipituuden p„„h„n. ----------------------------------------------------------------------------*/ { int koko=0,k; char *m; for (k=0; kjasenia; j++) if ( kerho->jasenet[j] ) kerho->jasenet[k++] = kerho->jasenet[j]; kerho->jasenia = k; kerho->nykyjasen = 0; return 0; } /****************************************************************************/ void /* */ tulosta_kenttalista( /* */ char *lista /* s Kent„t, jotka tulostetaan n„ytt””n. */ ) /* ** Aliohjelmalla tulostetaan kentt„lista n„ytt””n. Vain ne kent„t ** tulostetaan, joiden valintakirjain on mukana listassa. ** ** Tulostus: N„ytt””n ** Kutsuu: ----------------------------------------------------------------------------*/ { int k; for (k=0; knykyjasen >= kerho->jasenia ) tyhjenna_kaikki=1; else *jasen = *kerho->jasenet[kerho->nykyjasen]; for (k=0; kjasenia >= kerho->max_jasenia ) { uusi_koko = 3*(kerho->max_jasenia)/2; uusi_tila = realloc(kerho->jasenet,uusi_koko*sizeof(Jasen_tyyppi *)); if ( !uusi_tila ) return 1; kerho->jasenet=uusi_tila; kerho->max_jasenia=uusi_koko; } uusi_jasen = malloc(sizeof(Jasen_tyyppi)); if ( uusi_jasen==NULL ) return 1; *uusi_jasen = *jasen; kerho->jasenet[kerho->jasenia]=uusi_jasen; kerho->nykyjasen=kerho->jasenia; kerho->jasenia++; return 0; } static char *EI_VOI_LUODA = "J„senist”lle ei saada varattua tilaa muistista!"; /****************************************************************************/ char /* NULL =onnistui */ *luo_jasentaulukko( /* muut = virheilmoitus merkkijonona */ Kerho_tyyppi *kerho ,/* t K„sitelt„v„ kerho */ int koko /* s Kerhon maksimij„senm„„r„. */ ) /* ** Funktiolla luodaan kerhoon tyhj„ osoitintaulukko j„senist””n. Mik„li ** j„sentaulukkoa ei voida luoda, palautetaan virheilmoitus. ** Mik„li taulukko saadaan luotua, alustetaan se NULL-osoittimilla. ----------------------------------------------------------------------------*/ { int i; kerho->jasenet = malloc(koko*(sizeof(Jasen_tyyppi *))); kerho->max_jasenia=koko; kerho->jasenia=0; kerho->haku=NULL; if (!kerho->jasenet) return EI_VOI_LUODA; for (i=0; ijasenet[i]=NULL; return NULL; } /****************************************************************************/ char /* "" jos v„„r„ kent„n nro */ *viesti( /* Kent„n numeroa nro vastaava viesti */ int nro /* Kent„n numero, jonka viesti halutaan. */ ) /* ** Funktiolla palautetaan haluttua kentt„„ vastaava kent„n kysymisess„ ** tarvittava viesti. ** ----------------------------------------------------------------------------*/ { if ( nro<0 || KENTTIA<=nro ) return ""; return KENTAT[nro].hopute; } /****************************************************************************/ int /* 1 = lopetetaan sy”tt” */ kysy_kentta( /* 0 = OK */ int nro ,/* s Luettavan kent„n numero */ char *jono ,/* t Jono johon kent„n vastaus luetaan. */ int max_koko ,/* s Jonon maksimi koko. */ Tarkistus_funktio f ,/* s Funktio, jolla jonon oikeellisuus tark. */ Tarkistus_tyyppi *tark /* s Tarkistusfunktion parametri */ ) /* ** Funktiolla luetaan vastaus kentt„„n. ** ** Globaalit: POIS (jono, jolla sy”tt” katkaistaan) ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: lue_jono_oletus ----------------------------------------------------------------------------*/ { char apu[80]; Tarkistus_tulos_tyyppi f_paluu; int paluu; tark->kentta = nro; kopioi_jono(N_S(apu),jono); do { paluu = lue_jono_oletus(viesti(nro),OLET_ALKU,VAKANEN,apu,N_S(apu)); if ( paluu < OLETUS ) return 1; poista_tyhjat(apu); if ( strcmp(apu,POIS)==0 ) return 1; if (!f) break; /* Jollei tarkistusfunktiota, niin kaikki kelpaa! */ f_paluu = f(tark,apu); if ( f_paluu == TARK_LOPETUS ) return 1; if ( f_paluu == TARK_PAL_OLET ) kopioi_jono(N_S(apu),jono); } while ( f_paluu != TARK_OK ); kopioi_jono(jono,max_koko,apu); return 0; } /****************************************************************************/ int /* 0 = hommat OK */ kysy_jasenen_tiedot( /* 1 = halutaan pois kysymyksest„ */ Kerho_tyyppi *kerho ,/* s Kerho johon j„sent„ kysyt„„n */ Jasen_tyyppi *jasen ,/* s,t T„ytett„v„n j„senen tiedot */ int kysymys_tyyppi /* s Sy”tt”, p„ivitys, lis„ys? */ ) /* ** Funktiolla kysell„„n j„senen tiedot. Oletusarvoina k„ytet„„n ** jasenen alkuper„isi„ tietoja. ** Mik„li jonoa luettaessa pit„„ poistua, lopetetaan kysymykset ** ja j„senen alkuper„iset tiedot s„ilyv„t. ** palautetaan 1. ** Numeeriset kent„t muutetaan merkkijonoiksi ennen kysymist„. ** ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_kentta ** kentta_jonoksi, jono_kentaksi ----------------------------------------------------------------------------*/ { Jasen_tyyppi apu_jasen; Tarkistus_tyyppi tarkistus; char st[80]; int k=0; tarkistus.kerho = kerho; tarkistus.syotto_tyyppi = kysymys_tyyppi; tarkistus.jasen = &apu_jasen; apu_jasen=*jasen; k = 0; while ( k < KENTTIA ) { tarkistus.seuraava_kentta = k+1; kopioi_jono(N_S(st),kentta_jonoksi(k,&apu_jasen)); if ( kysy_kentta(k,N_S(st),KENTAT[k].tark_fun,&tarkistus) ) return 1; jono_kentaksi(k,&apu_jasen,st); k = tarkistus.seuraava_kentta; } if ( memcmp(jasen,&apu_jasen,sizeof(Jasen_tyyppi)) ) { kerho->muutettu = 1; *jasen = apu_jasen; } return 0; } /****************************************************************************/ int /* 0 = kentt„ OK */ kysy_haku( /* 1 = halutaan poistua */ Haku_tyyppi *haku ,/* s,t T„ytett„v„ hakutietue */ int nro /* s Kysytt„v„ kentt„ */ ) /* ** Funktiolla kysyt„„n kent„n tiedot. Oletusarvoina k„ytet„„n ** kent„n alkuper„isi„ tietoja. ** Mik„li kentt„„n vastataan q, lopetetaan kysymykset ja ** palautetaan 1. ** ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_kentta ----------------------------------------------------------------------------*/ { Tarkistus_tyyppi tark; return kysy_kentta(nro,N_S(haku[nro]),t_ok,&tark); } /****************************************************************************/ int /* 0 = hommat OK */ kysy_hakutiedot( /* 1 = halutaan pois kysymyksest„ */ Haku_tyyppi *haku /* s,t T„ytett„v„ hakutaulukko */ ) /* ** Funktiolla kysell„„n hakutaulukon tiedot. Oletusarvoina taulukon ** alkuper„iset tiedot. ** Mik„li johonkin kentt„„n vastataan q, lopetetaan kysymykset ja ** palautetaan 1. ** ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_haku ----------------------------------------------------------------------------*/ { int k; printf("== tarkoittaa, ett„ kent„n TŽYTYY olla tyhj„\n"); for (k = 0; k < KENTTIA; k++) { if ( kysy_haku(haku,k) ) return 1; } return 0; } /****************************************************************************/ int /* */ poista_jasen( /* 0 = onnistui, 1 = ep„onnistui */ Kerho_tyyppi *kerho ,/* s,t Kerho josta poistetaan. */ int poistettava /* s Poistettavan j„senen numero */ ) /* ** Funktiolla poistetaan j„sen listasta. Poisto varmistetaan k„ytt„j„lt„. ** Listaan laitetaan j„senen paikalle NULL ja itse j„sen h„vitet„„n. ** ** Sy”tt”: P„„tteelt„ ** Tulostus: N„yt”lle ** Kutsuu: odota_nappain ----------------------------------------------------------------------------*/ { char vastaus; printf("Haluatko todellakin poistaa j„senen %s (k/E):", kentta_jonoksi(0,kerho->jasenet[poistettava])); vastaus=odota_nappain("KE",'E',VAIN_ISOT); printf("\n"); if ( vastaus=='E' ) return 1; free(kerho->jasenet[poistettava]); kerho->jasenet[poistettava]=NULL; printf("J„sen poistettu!\n"); return 0; }