/****************************************************************************/ /* ** K E R H O R A K . C ** ** Kerhon rakenteeseen oleellisesti liittyvi„ aliohjelmia ** ** Aliohjelmat: ** tulosta_jasen - tulostaa j„senen valittuun tiedostoon ** alusta_jasen - alustaa j„senen kent„t„ tyhjiksi ** lisaa_jasen - lis„„ uuden j„senen rakenteeseen ** luo_jasentaulukko - luo j„senosoitintaulukon ** kysy_jasenen_tiedot - kysyy j„senen kaikkien kenttien tiedot ** ** ** ** ** Yleinen tietorakenne on seuraava: ** ** ** Kerho_tyyppi Jasen_tyyppi ** ------ ** | | ------ ** | | | | ** | 7 | |---->| | ** | 3 | jasenet | | | ------ ** | |------>|-----| | ------ | | ** ------ | 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 ** */ #include #include #include #include "mjonot.h" #include "kerho.h" #define OLET_ALKU 19 /* Oletuksen alkusarake */ #define VAKANEN 33 /* V„k„sen alkusarake */ /****************************************************************************/ void tulosta_jasen( /* */ FILE *f ,/* s Tiedosto johon tulostetaan */ Jasen_tyyppi *jasen /* s Tulostettava j„sen */ ) /* ** Funktiolla tulostetaan j„sen valittuun tiedostoon. ** Mik„li numeerisessa kent„ss„ on tyhj„ arvo, ei sit„ tulosteta! ** ** Tulostus: tiedostoon f ** Kutsuu: kentta_jonoksi ** kentan_indeksi ----------------------------------------------------------------------------*/ { char st[80]; fprintf(f," %s %s\n", jasen->nimi, jasen->sotu); fprintf(f," %s %s %s\n", jasen->katuosoite, jasen->postinumero, jasen->postiosoite); fprintf(f," k: %s t: %s a: %s\n",jasen->kotipuhelin, jasen->tyopuhelin, jasen->autopuhelin); fprintf(f," Liittynyt %s",int_jonoksi(N_S(st),jasen->liittymisvuosi,"%d")); fprintf(f,". J„senmaksu %s",double_jonoksi(N_S(st),jasen->jmaksu,"%5.2lf")); fprintf(f," mk. Maksettu %s",double_jonoksi(N_S(st),jasen->maksu,"%5.2lf")); fprintf(f," mk.\n"); fprintf(f," %s\n",jasen->lisatietoja); } /****************************************************************************/ void /* */ alusta_jasen( /* */ Kerho_tyyppi *kerho ,/* s Kerho, jonka j„sen alustetaan. */ Jasen_tyyppi *jasen /* t Alustettava j„sen. */ ) /* ** Aliohjelmalla alustetaan j„senen tiedot kerhon nykyj„senen mukaan. ** Ne kent„t, jotka halutaan lis„yksess„ tyhjent„„, tyhjennet„„n. ** Mik„li kerhossa ei ole j„seni„, tyhjennet„„n kaikki kent„t! ** ** Globaalit: KENTAT ----------------------------------------------------------------------------*/ { if ( kerho->nykyjasen >= kerho->jasenia ) { strcpy(jasen->nimi, ""); strcpy(jasen->sotu, ""); strcpy(jasen->katuosoite, ""); strcpy(jasen->postinumero, ""); strcpy(jasen->postiosoite, ""); strcpy(jasen->kotipuhelin, ""); strcpy(jasen->tyopuhelin, ""); strcpy(jasen->autopuhelin, ""); jasen->liittymisvuosi= TYHJA_ARVO; jasen->jmaksu = TYHJA_ARVO; jasen->maksu = TYHJA_ARVO; strcpy(jasen->lisatietoja, ""); } else { *jasen = *kerho->jasenet[kerho->nykyjasen]; jasen->nimi[0]=0; jasen->sotu[0]=0; jasen->autopuhelin[0]=0; jasen->lisatietoja[0]=0; } } /****************************************************************************/ int /* */ lisaa_jasen( /* 0 = onnistui 1 = ei onnistu */ Kerho_tyyppi *kerho ,/* s,t K„sitelt„v„ kerho */ Jasen_tyyppi *jasen /* s Lis„tt„v„ j„sen */ ) /* ** Funktiolla lis„t„„n uusi j„sen kerhoon. EI tarkisteta esiintyyk” ** nimi jo ennest„„n. Mik„li tilaa ei ole, yritet„„n allokoida uutta ** tilaa 50% maksimim„„r„„n n„hden lis„„. ** ** Algoritmi: Jos uudelle j„senelle saadaan varattua tilaa, lis„t„„n ** uuden paikan osoite taulukkoon jo kopioidaan tiedot ** uuteen paikkaan. ----------------------------------------------------------------------------*/ { Jasen_tyyppi *uusi_jasen,**uusi_tila; int uusi_koko; if ( kerho->jasenia >= 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; 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. ** ----------------------------------------------------------------------------*/ { switch (nro) { case NIMIKENTTA : return "J„senen nimi" ; case SOTUKENTTA : return "Sotu" ; case KATUKENTTA : return "Katuosoite" ; case POSTINROKENTTA : return "Postinumero" ; case POSTIOSKENTTA : return "Postiosoite" ; case KOTIPUHKENTTA : return "Kotipuhelin" ; case TYOPUHKENTTA : return "Ty”puhelin" ; case AUTOPUHKENTTA : return "Autopuhelin" ; case LIITTYMISKENTTA : return "Liittymisvuosi" ; case JMAKSUKENTTA : return "J„senmaksu mk" ; case MAKSUKENTTA : return "Maksettu maksu mk"; case LISATIETOJAKENTTA: return "Lis„tietoja" ; default : return "" ; } } /****************************************************************************/ 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 ** jono_intiksi, int_jonoksi, jono_doubleksi, double_jonoksi ----------------------------------------------------------------------------*/ { #define LUE_KENTTA(jono,t_fun) \ if ( kysy_kentta(k++,N_S(jono),t_fun,&tarkistus) ) return 1; 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; LUE_KENTTA(apu_jasen.nimi ,t_nimi); LUE_KENTTA(apu_jasen.sotu ,t_sotu); LUE_KENTTA(apu_jasen.katuosoite ,t_katu); LUE_KENTTA(apu_jasen.postinumero,t_numeerinen); LUE_KENTTA(apu_jasen.postiosoite,t_isoksi); LUE_KENTTA(apu_jasen.kotipuhelin,t_puh); LUE_KENTTA(apu_jasen.tyopuhelin ,t_puh); LUE_KENTTA(apu_jasen.autopuhelin,t_puh); int_jonoksi(N_S(st),apu_jasen.liittymisvuosi,"%d"); LUE_KENTTA(st ,t_vuosi_1900); apu_jasen.liittymisvuosi = jono_intiksi(st,"%d"); double_jonoksi(N_S(st),apu_jasen.jmaksu,"%4.2lf"); LUE_KENTTA(st ,t_ok); apu_jasen.jmaksu = jono_doubleksi(st,"%lf"); double_jonoksi(N_S(st),apu_jasen.maksu,"%4.2lf"); LUE_KENTTA(st ,t_ok); apu_jasen.maksu = jono_doubleksi(st,"%lf"); LUE_KENTTA(apu_jasen.lisatietoja,t_ok ); *jasen = apu_jasen; return 0; #undef LUE_KENTTA }