/* URHEILUSEURA KAATAJAT JˇSENREKISTERI ==================================== Harjoitus C134 10.12.91 Tommi Ronkainen */ /***************************************************************************** VAKIOT *****************************************************************************/ #define CPP 1 /* C++ versio ? */ #define MAXNIMI 40 /* Nimien maksimi pituus */ #define MAXOSOITE 40 /* L„hi- ja postiosoitteen maksimi pituus */ #define MAXJASEN 500 /* J„sen taulukon maksimi koko */ #define MAXLISENSSI 10 /* Lisenssi numeron maksimi pituus merkkein„ */ /* C++ Dialoogiformaatti-makrot editointi kenttiin */ #define NIMI_F "uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu" #define NIMIHAKU_F "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" #define LAHIOSOITE_F "uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu" #define POSTIOSOITE_F "99999uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu" #define OSOITEHAKU_F "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" #define SOTU_F "999999-999U" #define VUOSI_F "1999" #define LISENSSI_F "UUUUUUUUU" /* Formaatissa merkeill„ seuraavat merkitykset x - kaikki merkit u - Vastaa alku_iso_jono() DemoTeht„v„n merkkijonoja U - muunnetaan kaikki isoiksi 9 - numeroita 0 - numeroita ja '.' + - numeroita ja '-' ta '+' Kaikki muut merkit tulkitaan siten ett„ kyseiseen paikkaan on pakko sy”tt„„ vastaava merkki esim sotu: 999999-999U odottaa kuuden numeron j„lkeen miinusmerkki„ */ /***************************************************************************** INCLUDET *****************************************************************************/ #include #ifdef CPP # include "dialog.h" # include "standard.h" # include "input.h" # include #else # include # include #endif /***************************************************************************** STRUKTUURIT *****************************************************************************/ /* OSOITE ------ */ typedef struct OSOITE { struct OSOITE *c_o; /* ptr jonkun toisen osoitteeseen tai NULL */ char lahi[MAXOSOITE]; char posti[MAXOSOITE]; } osoite; /* LUOKKA TYYPPI ------------- Kuvaa j„senen kilpailusarjaa */ typedef enum {Alle_15,Alle_18,Nainen,Yleinen_A,Yleinen_B,Yleinen_C,Ikamies} luokka_t; /* AKTIIVISUUS TYYPPI ------------------ Kertoo j„senen aktiivisuuden j„senmaksujen suhteen */ typedef enum {Maksanut,Maksamatta,Eronnut} aktiivisuus_t; /* JASEN ----- */ typedef struct { char etunimi[MAXNIMI]; char sukunimi[MAXNIMI]; osoite osoite; char sotu[12]; aktiivisuus_t aktiivisuus; unsigned int liit_vuosi; /* Liittymis vuosi */ char lisenssi[MAXLISENSSI]; /* Kilpailulisenssi */ luokka_t luokka; } jasen; /* SEURA ----- */ typedef struct { char nimi[MAXNIMI]; /* Seuran nimi */ int lkm; /* J„senien lukum„„r„ */ jasen *jasen[MAXJASEN]; /* Ptrit j„seniin */ } seura; /* INDEKSI TAULUKKO ---------------- Indeksi taulukko jota k„ytet„„n hakuehtojen t„ytt„vien j„senten indeksointiin Listassa */ typedef struct { int oletus; /* Oletus j„sen */ int lkm; /* Hakuehdot t„ytt„vien j„senten lkm */ int i[MAXJASEN]; /* Indeksit */ } indeksi; /* HAKUEHDOT --------- Sis„lt„„ Listan j„senten valintaperusteet. */ typedef struct { char etunimi[MAXNIMI]; char sukunimi[MAXNIMI]; char lahiosoite[MAXOSOITE]; char postiosoite[MAXOSOITE]; } hakuehdot; /***************************************************************************** ESITTELYT *****************************************************************************/ void warning(char *msg); void tulosta_oletus_jasen(); int jasen_dialogi(jasen *j,char *otsikko); /***************************************************************************** APU-FUNKTIOT *****************************************************************************/ /*--------------------------------------------------------------------------*/ int vertaa_jonoja(char *jono,char *maski) /*---------------------------------------------------------------------------- Suorita kahden merkkijono hakuvertailu jono - testattava maski - hakuehto --> 1 - jos jono t„ytt„„ hakuehdon T„ll„ hetkell„ ainoa hakuehto on: maski sis„ltyy jonoon (case independent) ----------------------------------------------------------------------------*/ { int i; if(*maski=='\0') return 1; while(*jono) { for(i=0; *(maski+i); i++) if (toupper(*(maski+i)) != toupper(*(jono+i))) break; if(*(maski+i)=='\0') return 1; jono++; } return 0; } /*--------------------------------------------------------------------------*/ void stringcopy(char *s,char *d) /*---------------------------------------------------------------------------- Kopioi merkkijono s - alkup d - kohde ----------------------------------------------------------------------------*/ { while((*d++=*s++)!=0); } /***************************************************************************** LISTAN KˇSITTELY *****************************************************************************/ seura *EDITOITAVA; /* Globaali muuttuja kaikille SY™TT™/TULOSTUS ja LISTAN KˇSITTELY-rutiineille. Sis„lt„ editoitavan seuran osoitteen */ indeksi INDEKSI={0,0}; /* Globaali indeksitaulukko, jossa s„ilytet„„n j„senten j„rjestyst„ */ /* KORJAUS ======= N„m„ globaalit muuttujat ovat poistettavissa seuraavasti: - Lis„t„„n CommandButton tyypin olioille yksi parametri, joka on pointteri painikkeen asetuksiin etc. ohjelmoijan valitsemaan tietotyyppiin. - Yhdistet„„n 'indeksi'-struktuuriin my”s tieto editoitavasta seurasta l. siirret„„n ptr EDITOITAVA em. struktuuriin. - Siirret„„n *EDITOITAVA ja INDEKSI menu()-funktion paikalliseksi struktuuriksi - Annetaan kaikille p„„menun CommandButton:eille t„m„n osoite parametriksi - Muutetaan CommandButton::HandleKey() - oliofunktiota siten ett„ se l„hett„„ t„m„n ptrin eteenp„in painalluksen k„sittelij„lle - Muutetaan kaikki CommandButton-k„sittelij„t (tunnistettavissa tyhj„st„ (void *) parametrim„„rittelyst„), siten ett„ ne ottavat vastaan my”s t„m„n uuden ptrin, sek„ my”s niiden dialoogien Commandbutton:it vastaavasti siten, ett„ ne my”s l„hett„v„t ptrin eteenp„in - Korjataan kaikki viittaukset INDEKSIin ja EDITOITAVAan vastaaviksi /*--------------------------------------------------------------------------*/ void alkuun(void *) /*---------------------------------------------------------------------------- Siirry listan alkuun ----------------------------------------------------------------------------*/ { INDEKSI.oletus=0; tulosta_oletus_jasen(); } /*--------------------------------------------------------------------------*/ void loppuun(void *) /*---------------------------------------------------------------------------- Siirry listan loppuun ----------------------------------------------------------------------------*/ { INDEKSI.oletus=(INDEKSI.lkm ? INDEKSI.lkm-1 : 0); tulosta_oletus_jasen(); } /*--------------------------------------------------------------------------*/ void edellinen(void *) /*---------------------------------------------------------------------------- Siirry edelliseen j„seneen ----------------------------------------------------------------------------*/ { if(INDEKSI.oletus > 0) { INDEKSI.oletus--; tulosta_oletus_jasen(); } } /*--------------------------------------------------------------------------*/ void seuraava(void *) /*---------------------------------------------------------------------------- Siirry seuraavaan j„seneen ----------------------------------------------------------------------------*/ { if(INDEKSI.oletus < INDEKSI.lkm-1) { INDEKSI.oletus++; tulosta_oletus_jasen(); } } /*--------------------------------------------------------------------------*/ void valitse_kaikki() /*---------------------------------------------------------------------------- Valitaan kaikki j„senet listaan, eli muodostetaan indeksi taulukko alkiolla 0,1,2,...,n --> p„ivitetty INDEKSI ----------------------------------------------------------------------------*/ { int i; for(i=0; i < EDITOITAVA->lkm; i++) INDEKSI.i[i]=i; INDEKSI.lkm=EDITOITAVA->lkm; INDEKSI.oletus=0; tulosta_oletus_jasen(); } /*--------------------------------------------------------------------------*/ void muodosta_uusi_lista(hakuehdot *h) /*---------------------------------------------------------------------------- Suorita haku h - hakuehdot --> p„ivitetty INDEKSI ----------------------------------------------------------------------------*/ { int i,idx=0; jasen *j; for(i=0; ilkm; i++) { j=EDITOITAVA->jasen[i]; if (vertaa_jonoja(j->etunimi,h->etunimi) && vertaa_jonoja(j->sukunimi,h->sukunimi) && vertaa_jonoja(j->osoite.lahi,h->lahiosoite) && vertaa_jonoja(j->osoite.posti,h->postiosoite)) /* T„h„n lis„„ haku ehtoja eri kentille */ INDEKSI.i[idx++]=i; } INDEKSI.lkm=idx; INDEKSI.oletus=0; tulosta_oletus_jasen(); } /***************************************************************************** REKISTERIN KˇSITTELY *****************************************************************************/ /*--------------------------------------------------------------------------*/ jasen *uusi_jasen(seura *s,indeksi *idx) /*---------------------------------------------------------------------------- Varataan muistista tila uudelle j„senelle, nollataan kent„t ja sijoitetaan sen osoite jasentaulukkoon. s - J„sen rekisteri, johon lis„ys suoritetaan --> Uuuden j„senen osoite ----------------------------------------------------------------------------*/ { jasen *uusi=NULL; if (s->lkm==MAXJASEN) warning("J„sentaulukko t„ynn„"); if(!(uusi=(jasen *)malloc(sizeof(jasen)))) warning("Muisti loppui. En voi lis„t„ uusia j„seni„."); else { s->jasen[s->lkm]=uusi; uusi->etunimi[0]= uusi->sukunimi[0]= uusi->osoite.lahi[0]= uusi->osoite.posti[0]= uusi->sotu[0]= uusi->lisenssi[0]=0; uusi->liit_vuosi=1991; uusi->luokka=Yleinen_A; uusi->aktiivisuus=Maksanut; uusi->osoite.c_o=NULL; idx->i[idx->lkm]=s->lkm; idx->oletus=idx->lkm; idx->lkm++; s->lkm++; } return uusi; } /*--------------------------------------------------------------------------*/ void muuta_tietoja(void *) /*---------------------------------------------------------------------------- Oletus j„senen tietojen muuttaminen. Kopioidaan j„sen v„liaikaiseen muuttujaan ja jos muutokset hyv„ksyt„„n kopioidaan se takaisin ----------------------------------------------------------------------------*/ { jasen muutettava; if (INDEKSI.lkm) { muutettava=*(EDITOITAVA->jasen[INDEKSI.oletus]); jasen_dialogi(&muutettava,"KORJAA TIETOJA"); *(EDITOITAVA->jasen[INDEKSI.oletus])=muutettava; tulosta_oletus_jasen(); } } /*--------------------------------------------------------------------------*/ void lisaa_jasen(void *) /*---------------------------------------------------------------------------- Uuden j„senen lis„ys. Staattinen jasen muuttuja s„ilytt„„ oletus arvot kentille, kuten esim osoitteena sama kuin edelliselle. ----------------------------------------------------------------------------*/ { static jasen lisattava={"","",{NULL,"",""},"",Maksanut,1991,"",Yleinen_A}; jasen *paikka; lisattava.etunimi[0]= lisattava.sukunimi[0]= lisattava.sotu[0]='\0'; if (jasen_dialogi(&lisattava,"LISˇˇ JˇSEN")) if((paikka=uusi_jasen(EDITOITAVA,&INDEKSI))!=NULL) { *paikka=lisattava; tulosta_oletus_jasen(); } } /***************************************************************************** SY™TT™ JA TULOSTUS ================== T„ss„ ohjelman osassa on kaikki rutiinit, jotka kutsuvat ei-standardeja oliofunktioita. *****************************************************************************/ /*--------------------------------------------------------------------------*/ void waitkey(char *viesti) /*---------------------------------------------------------------------------- Odota n„pp„imen painnallus viesti - N„yt”lle tulostuva teksti ----------------------------------------------------------------------------*/ { #ifdef CPP Frame w(20,12,40,1,WHITE,GREEN,sizeof(char*)); w+=String(0,0,40,Center); w.Exec(&viesti); #else if(*viesti) printf("%s\n",viesti); while(!getchar()); #endif } /*--------------------------------------------------------------------------*/ void warning(char *viesti) /*---------------------------------------------------------------------------- Tulostetaan varoitus ja odotetaan n„pp„imen painallus viesti - N„yt”lle tulostuva teksti ----------------------------------------------------------------------------*/ { #ifdef CPP Frame varoitus(20,10,40,4,WHITE,RED,sizeof(char*),"VAROITUS"); varoitus+=String(0,1,40,Center,YELLOW); varoitus+=StaticText(0,3,40,"Paina n„pp„int„",Center); varoitus.Exec(&viesti); #else printf("\n========\n" "Varoitus\n" "========\n" "%s\n",viesti); waitkey("===============\nPaina Return"); #endif } /*--------------------------------------------------------------------------*/ void system_error(char *viesti) /*---------------------------------------------------------------------------- Tulostetaan virheilmoitus ja poistutaan viesti - N„yt”lle tulostuva teksti ----------------------------------------------------------------------------*/ { #ifdef CPP error(viesti); #else printf("\n=======================\n" "Ohjelman sis„inen virhe\n" "=======================\n" "%s\n",viesti); exit(1); #endif } /*--------------------------------------------------------------------------*/ void nimea_rekisteri(void *) /*---------------------------------------------------------------------------- Rekisterin nime„minen. EDITOITAVA->nimi - uusi nimi ----------------------------------------------------------------------------*/ { char uusi_nimi[MAXNIMI]; Frame nimi(25,10,MAXNIMI+4,4,YELLOW,GREEN,MAXNIMI,"REKISTERIN NIMI"); nimi+=CharField(1,0,NIMI_F); nimi+=ExitButton(MAXNIMI-10,2," OK ",1,ENTER,WHITE,BLUE); stringcopy(EDITOITAVA->nimi,uusi_nimi); if(nimi.Exec(uusi_nimi)) stringcopy(uusi_nimi,EDITOITAVA->nimi); } /*--------------------------------------------------------------------------*/ void muut_toiminnot(void *) /*---------------------------------------------------------------------------- Muiden toimintojen valikko. (vain C++ versio; C-version muut toiminnot k„sitell„„n p„„menussa) ----------------------------------------------------------------------------*/ { Frame muut(42,10,35,13,WHITE,BLUE,0,"MUUT TOIMINNOT"); muut+=CommandButton(2,1," Tulosta Lista Printterille ",'P'); muut+=CommandButton(2,3," Nime„ Rekisteri ",'N',nimea_rekisteri); muut+=CommandButton(2,5," Hae Rekisteri ",'H'); muut+=CommandButton(2,7," Tallenna Rekisteri ",'T'); muut+=CommandButton(2,9," Poista Koko Lista "); muut+=CommandButton(2,11," Poista Koko Rekisteri "); muut.Exec(); } /*--------------------------------------------------------------------------*/ void suorita_haku(void *) /*---------------------------------------------------------------------------- Haku listaan. Kysyt„„n hakuparametrit ja p„ivitet„„n listan indeksi taulukko. ehdot - staattinen taulukko joka s„ilytt„„ viimeksi k„ytetyn hakuehdon ----------------------------------------------------------------------------*/ { static hakuehdot ehdot={"","","",""}; #if CPP int w=45,h=16; if (EDITOITAVA->lkm) { Frame haku(5,12,w,h,WHITE,MAGENTA,sizeof(hakuehdot),"LISTAN HAKUEHDOT"); haku+=ExitButton(13,1," Valitse Kaikki ",1); haku+=StaticText(2,3,w,"Etunimi",Left); haku+=CharField(2,4,NIMIHAKU_F,BLUE,WHITE); haku+=StaticText(2,5,w,"Sukunimi",Left); haku+=CharField(2,6,NIMIHAKU_F,BLUE,WHITE); haku+=StaticText(2,7,w,"L„hiosoite",Left); haku+=CharField(2,8,OSOITEHAKU_F,BLUE,WHITE); haku+=StaticText(2,9,w,"Postiosoite",Left); haku+=CharField(2,10,OSOITEHAKU_F,BLUE,WHITE); /* T„h„n lis„„ kentti„ hakuehdoille */ haku+=ExitButton(13,h-2," Suorita Haku ",2); switch (haku.Exec(&ehdot)) { case 1: valitse_kaikki(); break; case 2: muodosta_uusi_lista(&ehdot); break; } } #else #endif } /*--------------------------------------------------------------------------*/ int jasen_dialogi(jasen *j,char *otsikko) /*---------------------------------------------------------------------------- Dialogi j„senen korjausta ja lis„yst„ varten j - editoitavan jasen-struktuurin osoite --> 0 - peru muutokset 1 - hyv„ksy muutokset j - muutettu jasen ----------------------------------------------------------------------------*/ { jasen editoitava=*j; int ok=0; #if CPP Frame dialogi(2,10,43,13,YELLOW,CYAN,sizeof(jasen),otsikko); dialogi+=StaticText(1,0,40,"Etunimet",Left); dialogi+=CharField(1,1,NIMI_F); dialogi+=StaticText(1,2,40,"Sukunimi",Left); dialogi+=CharField(1,3,NIMI_F); dialogi+=NullObject(sizeof(osoite*)); dialogi+=StaticText(1,4,40,"Lahiosoite",Left); dialogi+=CharField(1,5,LAHIOSOITE_F); dialogi+=StaticText(1,6,40,"Postinumero ja -osoite",Left); dialogi+=CharField(1,7,POSTIOSOITE_F); dialogi+=StaticText(1,8,4,"Sotu",Left); dialogi+=CharField(1,9,SOTU_F); dialogi+=NullObject(sizeof(int)); dialogi+=StaticText(15,8,5,"Vuosi",Left); dialogi+=IntField(15,9,VUOSI_F); dialogi+=StaticText(22,8,8,"Lisenssi",Left); dialogi+=CharField(22,9,LISENSSI_F); dialogi+=NullObject(sizeof(int)); dialogi+=ExitButton(33,11," OK ",1); ok=dialogi.Exec(&editoitava); #endif if (ok) *j=editoitava; return ok; } /*--------------------------------------------------------------------------*/ void tulosta_oletus_jasen() /*---------------------------------------------------------------------------- Tulosta oletus j„senen tiedot ----------------------------------------------------------------------------*/ { #if CPP int i,lopetus,w=35,h=9; static Window lista(42,1,w,h,WHITE,RED,FRAME_222,"LISTA"); lista.Fill(); if(INDEKSI.lkm) { i=INDEKSI.oletus-h/2; if (i+h-1>=INDEKSI.lkm) i=INDEKSI.lkm-h; if (i<0) i=0; lopetus=i+h-1; if (lopetus>=INDEKSI.lkm) lopetus=INDEKSI.lkm-1; while(i<=lopetus) { if (i==INDEKSI.oletus) lista.Fg(YELLOW); else lista.Fg(WHITE); lista.Print(EDITOITAVA->jasen[INDEKSI.i[i]]->sukunimi); lista.Plot(' '); lista.Print(EDITOITAVA->jasen[INDEKSI.i[i]]->etunimi); lista.Plot(' '); lista.Print(EDITOITAVA->jasen[INDEKSI.i[i]]->sotu); lista.Print("\n"); i++; } } else lista.Print("Ei hakuehtoja t„ytt„vi„ j„seni„!"); #else #endif } /*--------------------------------------------------------------------------*/ void menu(seura *s) /*---------------------------------------------------------------------------- Ohjelman p„„menun ja valintojen k„sittely s - k„sitelt„v„ seura ----------------------------------------------------------------------------*/ { EDITOITAVA=s; #if CPP int mw=30,mh=22; // Menuboxin koko Frame menu(8,1,mw,mh,WHITE,BLUE,sizeof(seura),"PˇˇMENU"); menu+=StaticText(0,0,mw,"J„senrekisteri",Center,YELLOW); menu+=CharArray(0,1,mw,MAXNIMI); menu+=StaticText(mw/2-3,2,mw/2," J„sent„",Left); menu+=Integer(0,2,mw/2-3,Right); menu+=NullObject(sizeof(jasen*)*MAXJASEN); menu+=CommandButton(mw/2-4,4 ," Alkuun ",HOME,alkuun); menu+=CommandButton(mw/2-10,6," <-- ",LEFT,edellinen); menu+=CommandButton(mw/2+1,6 ," --> ",RIGHT,seuraava); menu+=CommandButton(mw/2-4,8 ," Loppuun ",END,loppuun); menu+=CommandButton(1,10," Lis„„ Uusi J„sen ",'L',lisaa_jasen); menu+=CommandButton(1,12," Korjaa J„senen Tietoja ",'K',muuta_tietoja); menu+=CommandButton(1,14," Etsi J„sen Listasta ",'E'); menu+=CommandButton(1,16," J„rjest„ Lista ",'J'); menu+=CommandButton(1,18," Suorita Uusi Haku Listaan ",'H',suorita_haku); menu+=CommandButton(1,20," Muut Toiminnot ",'M',muut_toiminnot); tulosta_oletus_jasen(); menu.Exec(EDITOITAVA); #endif } /***************************************************************************** MASSAMUISTI TOIMINNOT *****************************************************************************/ /***************************************************************************** PˇˇOHJELMA JA DEBUGGAUS APUFUNKTIOT *****************************************************************************/ /*--------------------------------------------------------------------------*/ void luo_testi_jasenet(seura *s) /*---------------------------------------------------------------------------- Luodaan testi j„senet virallisen luontifunktion avulla ja kopioidaan niille arvot lokaalista taulukosta. s - Muodostettavan seuran osoite ----------------------------------------------------------------------------*/ { int i; jasen testaajat[]= {{"Hemmo","Laiskiainen",{NULL,"Mukulakuja 8","29310 ˇikk„„"}, "010172-123G",Maksanut,1990,"101",Alle_18}, {"Jurpo","Turpeinen",{NULL,"T”lp„s","10021 Nakkila 21"}, "031264-441S",Maksanut,1989,"102",Yleinen_A}, {"Hyrkk”","V„h„kyr”",{NULL,"Polku 77","12300 Vehni„"}, "220451-1113",Maksanut,1968,"103",Ikamies}, {"Tiltu","V„h„kyr”",{NULL,{'\0'},{'\0'}}, "170980-112E",Maksanut,1991,"103B",Alle_15}}; for(i=0; i<4 ; *(uusi_jasen(s,&INDEKSI))=testaajat[i++]); s->jasen[3]->osoite.c_o=&s->jasen[2]->osoite; /* ??? LAITON ??? */ } int main(void) { seura kaatajat={"Kaatajat",0}; luo_testi_jasenet(&kaatajat); menu(&kaatajat); return 0; }