/****************************************************************************/ /* ** P E L A A R A K . C ** ** Sarjan rakenteeseen oleellisesti liittyvi„ pelaajien k„sittely aliohjelmia ** ** Aliohjelmat: ** p_poista_NULL - poistaa osoitintaulukosta NULL-osoittimet ** tulosta_pkenttalista - tulostaa valittavaksi kaikki pelaajatietueen ** kent„t ** vastaa_esa_tikkanen - sijoitaa vakiopelaajan Esa Tikkanen ** (testej„ varten) ** tulosta_pelaaja - tulostaa pelaajan valittuun tiedostoon ** tulosta_pelaajat - tulostaa sarjan kaikki pelaajat ** kysy_pelaajan_kentta - kysyy pelaajan valitun kent„n tiedot ** kysy_pelaajan_tiedot - kysyy pelaajan kaikkien kenttien tiedot ** lisaa_pelaaja - lis„„ uuden pelaajan rakenteeseen ** lisaa_uusi_pelaaja - kysyy pelaajan tiedot ja lis„„ pelaajan sarjaan ** poista_pelaaja - varmistaa ja poistaa valitun pelaajan ** pelaajan_tietojen_korjailu -korjataan tai poistetaan pelaajan tietoja ** pelaajat - kysyy lis„t„„nk” vai korjataanko pelaajia ** luo_pelaajisto - luo pelaajaosoitintaulukon ** ** ** ** ** Yleinen pelaajatietorakenne on seuraava: ** ** ** Pelaajarekisterityyppi Pelaajatyyppi ** ------ ** | | ------ ** | | | | ** | 7 | |---->| | ** | 3 | pelaajat | | | ------ ** | |------>|-----| | ------ | | ** ------ | o--+-----| | | ** |-----| |----->| | ** | o--+------------| ------ ------ ** |-----| | | ** | o--+--------------------------->| | ** |-----| | | ** | o--+--? ------ ** |-----| ** | o--+--? ** |-----| ** | o--+--? ** |-----| ** | o--+--? ** |-----| ** ** ** Tekij„t: Vesa Lappalainen ** Ohjelmointikurssi 1991 ** Tehty: 13.11.1991 ** Muutettu: 17.12.1991/jaa ** Mit„ muutettu: Muuttujat ja muuttujien tyypit vastaamaan omaa ** harjoitusty”t„ ** */ #include #include #include #include #include "mjonot.h" #include "sarja.h" #define P_K_A(nimi) sizeof(((Pelaaja_tyyppi *)PKENTTIA)->nimi),\ offsetof(Pelaaja_tyyppi,nimi) /* ** P_K_A(nimi) ** Makro muuttaa Pelaajatyyppisen tietueen kent„n nimen ** kent„n kooksi ja alkupaikaksi tietueen alusta lukien. */ /* ** Taulukko, johon on ker„tty 'intiimit' tiedot kustakin Pelaajatietueen ** kent„st„. T„m„n taulukon avulla tietueen kaikkia kentti„ pystyt„„n ** sitten k„ytt„m„„n silmukassa: */ P_kentta_tyyppi PKENTAT[] = { {"Pelaajan sukunimi" ,"sukunimi" ,P_K_A(sukunimi) ,1,20}, {"Pelaajan etunimi" ,"etunimi" ,P_K_A(etunimi) ,1,20}, {"Syntym„aika" ,"syntyma_aika" ,P_K_A(syntyma_aika) ,1,07}, {"Pelipaikka" ,"pelipaikka" ,P_K_A(pelipaikka) ,0,15}, {"Joukkueen tunnus" ,"jtunnus" ,P_K_A(jtunnus) ,0,10}, {"Pelaajan numero" ,"numero" ,P_K_A(numero) ,1,03} }; int PKENTTIA = (sizeof(PKENTAT)/sizeof(P_kentta_tyyppi)); int PNIMIKENTTA = 0; char PKENTTAVALINNAT[50] = "123456789ABCDEFGHIJ ?+-" KORJ_POISTO JA_TAI; /****************************************************************************/ /* A L I O H J E L M A T */ /****************************************************************************/ int /* */ p_poista_NULL( /* 0 = poisto onnistui, 1 = ep„onnistui */ Pelaajarekisteri_tyyppi *sarja_pelaajat /* s pelaajarek josta NULL-os pois*/ ) /* ** Funktiolla poistetaan NULL osoittimet listasta. ** ** Algoritmi: Lukuosoitin ja kirjoitusosoitin, joiden v„limatkaa ** kasvatetaan ainakun l”ytyy poistettava. ** Esimerkki: ----------------------------------------------------------------------------*/ { int l,k=0; for (l=0; lpelaajia; l++) if ( sarja_pelaajat->pelaajat[l] ) sarja_pelaajat->pelaajat[k++] = sarja_pelaajat->pelaajat[l]; sarja_pelaajat->pelaajia = k; sarja_pelaajat->nykypelaaja = 0; return 0; } /****************************************************************************/ void /* */ tulosta_pkenttalista( /* */ 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. ** ** Globaalit: PKENTAT ** PKENTTAVALINNAT ** Tulostus: N„ytt””n ** Kutsuu: ----------------------------------------------------------------------------*/ { int i; printf("Valitse kentt„ jonka mukaan etsit„„n:\n"); for (i=0; isukunimi, "Tikkanen"); strcpy(pelaaja->etunimi, "Esa"); strcpy(pelaaja->syntyma_aika,"121264"); strcpy(pelaaja->pelipaikka,"hy”kk„„j„"); strcpy(pelaaja->numero, "11"); strcpy(pelaaja->jtunnus,"TPS"); } /****************************************************************************/ void tulosta_pelaaja( FILE *f, /* Tiedosto josta tulostetaan */ Pelaaja_tyyppi *pelaaja /* Pelaaja jonka tietoja tulostetaan */ ) /* ** Tulostus: N„ytt””n ** Tekij„: Juha Ala-Aho ** Pvm: 10.12.1991 ----------------------------------------------------------------------------*/ { fprintf(f," %2s %s, %s\n", pelaaja->numero, pelaaja->sukunimi, pelaaja->etunimi); fprintf(f," %s\n", pelaaja->syntyma_aika); fprintf(f," %s, %s\n", pelaaja->jtunnus, pelaaja->pelipaikka); } /****************************************************************************/ void tulosta_pelaajat( Pelaajarekisteri_tyyppi *sarja_pelaajat /*Pelaajarek jonka pelaajia tul*/ ) /* ** Kutsuu: tulosta_pelaaja ** odota_jotakin ** Tekij„: Vesa Lappalainen ** Pvm: 10.11.1991 ----------------------------------------------------------------------------*/ { int i; printf("\n\n"); printf("Tulostetaan pelaajat\n"); printf("====================\n"); printf("-----------------------------------------------------------\n"); for (i=0; ipelaajia; i++) { tulosta_pelaaja(stdout,sarja_pelaajat->pelaajat[i]); printf("\n"); } printf("-----------------------------------------------------------\n"); printf("Siin„ kaikki!\n"); odota_jotakin(); } /****************************************************************************/ char /* NULL = halutaan poistua */ *kysy_pelaajan_kentta( /* muuten vastattu kent„n arvo */ Pelaaja_tyyppi *pelaaja ,/* s,t T„ytett„v„n pelaajan tiedot */ int nro ,/* s Kysytt„v„ kentt„ */ int kysymys_tyyppi /* s Sy”tt”, p„ivitys, lis„ys? */ ) /* ** Funktiolla kysyt„„n kent„n tiedot. Oletusarvoina k„ytet„„n ** pelaajien alkuper„isi„ tietoja. ** Mik„li kentt„„n vastataan q, lopetetaan kysymykset ja ** palautetaan NULL ** ** Globaalit: PKENTAT ** POIS (jono, jolla sy”tt” katkaistaan) ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: lue_jono_oletus ** Tekij„: Vesa Lappalainen ** Pvm: 10.11.1991 ----------------------------------------------------------------------------*/ { #define OLET_ALKU 19 /* Oletuksen alkusarake */ #define VAKANEN 33 /* V„k„sen alkusarake */ int paluu; char *p, jono[80]; p = PKENTTA(nro,pelaaja); paluu=lue_jono_oletus(PKENTAT[nro].hopute,OLET_ALKU,VAKANEN,p,P_N_S(jono)); /* Vain kunnes saadaan paremmat tarkistukset */ if ( kysymys_tyyppi!=SYOTTO && nro==PNIMIKENTTA && !jono[0] ) return NULL; if ( paluu < OLETUS ) return NULL; if ( strcmp(jono,POIS)==0 ) return NULL; poista_tyhjat(jono); kopioi_jono(p,PKENTAT[nro].koko,jono); return p; } /****************************************************************************/ int /* 0 = hommat OK */ kysy_pelaajan_tiedot( /* 1 = halutaan pois kysymyksest„ */ Pelaaja_tyyppi *pelaaja ,/* s,t T„ytett„v„n pelaajan tiedot */ int kysymys_tyyppi /* s Sy”tt”, p„ivitys, lis„ys? */ ) /* ** Funktiolla kysell„„n pelaajan tiedot. Oletusarvoina k„ytet„„n ** pelaajien alkuper„isi„ tietoja. Mik„li kyseess„ on lis„ys tai ** p„ivitys, ei nimikentt„„n voi vastata tyhj„ll„, siis palautetaan 1. ** Mik„li johonkin kentt„„n vastataan q, lopetetaan kysymykset ja ** palautetaan q. ** ** Globaalit: PKENTAT ** POIS (jono, jolla sy”tt” katkaistaan) ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_pelaajan_kentta ** Tekij„: Vesa Lappalainen ** Pvm: 10.11.1991 ----------------------------------------------------------------------------*/ { int k; Pelaaja_tyyppi apu_pelaaja; apu_pelaaja=*pelaaja; for (k=0; kpelaajia >= sarja_pelaajat->max_pelaajia ) { uusi_koko = 3 * (sarja_pelaajat->max_pelaajia)/2; uusi_tila = realloc(sarja_pelaajat->pelaajat, uusi_koko*sizeof(Pelaaja_tyyppi *)); if ( !uusi_tila ) return 1; sarja_pelaajat->pelaajat=uusi_tila; sarja_pelaajat->max_pelaajia=uusi_koko; } uusi_pelaaja = malloc(sizeof(Pelaaja_tyyppi)); if ( uusi_pelaaja==NULL ) return 1; *uusi_pelaaja = *pelaaja; sarja_pelaajat->pelaajat[sarja_pelaajat->pelaajia]=uusi_pelaaja; sarja_pelaajat->nykypelaaja=sarja_pelaajat->pelaajia; sarja_pelaajat->pelaajia++; return 0; } /****************************************************************************/ void /* */ lisaa_uusi_pelaaja( /* */ Pelaajarekisteri_tyyppi *sarja_pelaajat /* s,t Pelaajarek johon lis„t„„n */ ) /* ** Aliohjelmalla kysell„„n uusia pelaajia kunnes nimeksi annetaan [RET] ** ** Globaalit: PKENTAT (lista kenttien koosta ja alkukohdista) ** Sy”tt”: P„„tteelt„ ** Tulostus: N„ytt””n ** Kutsuu: kysy_pelaajan_tiedot ** tulosta_pelaaja ** kylla_vastaus ** lisaa_pelaaja ** Tekij„: Vesa Lappalainen ** Pvm: 10.11.1991 ----------------------------------------------------------------------------*/ { Pelaaja_tyyppi pelaaja; int i,tyhjenna_kaikki=0; printf("\n\n"); printf("Uuden pelaajan lis„ys\n"); printf("=====================\n"); while (1) { /* Tyhjennet„„n tarvittavat kent„t oletusarvosta */ if (sarja_pelaajat->nykypelaaja >= sarja_pelaajat->pelaajia) tyhjenna_kaikki=1; else pelaaja = *sarja_pelaajat->pelaajat[sarja_pelaajat->nykypelaaja]; for (i=0; ipelaajia); printf("Anna uusi pelaajan nimi\n"); do { /* vastaa_esa_tikkanen(&pelaaja); */ if (kysy_pelaajan_tiedot(&pelaaja,LISAYS)) return; printf("Lis„t„„nk”\n"); tulosta_pelaaja(stdout,&pelaaja); printf(":"); } while ( !kylla_vastaus() ); if ( lisaa_pelaaja(sarja_pelaajat,&pelaaja) ) { printf("\nLis„ys ei onnistunut!\n"); odota_jotakin(); } } } /****************************************************************************/ int /* */ poista_pelaaja( /* 0 = onnistui, 1 = ep„onnistui */ Pelaajarekisteri_tyyppi *sarja_pelaajat,/* s,t Pelaajarek josta poistetaan*/ int poistettava /* s Poistettavan pelaajan numero*/ ) /* ** Funktiolla poistetaan pelaaja listasta. Poisto varmistetaan k„ytt„j„lt„. ** Listaan laitetaan pelaajan paikalle NULL ja itse pelaaja h„vitet„„n. ** ** Sy”tt”: P„„tteelt„ ** Tulostus: N„yt”lle ** Kutsuu: odota_nappain ----------------------------------------------------------------------------*/ { char vastaus; printf("Haluatko todellakin poistaa pelaajan %s (k/E):", PKENTTA(PNIMIKENTTA,sarja_pelaajat->pelaajat[poistettava])); vastaus=odota_nappain("KE",'E',VAIN_ISOT); printf("\n"); if ( vastaus=='E' ) return 1; free(sarja_pelaajat->pelaajat[poistettava]); sarja_pelaajat->pelaajat[poistettava]=NULL; printf("Pelaaja poistettu!\n"); return 0; } /****************************************************************************/ void pelaajan_tietojen_korjailu( Pelaajarekisteri_tyyppi *sarja_pelaajat /* s,t Pelaajarek jota korjaillaa*/ ) /* ** Aliohjelmalla korjataan pelaajan tietoja tai poistetaan pelaaja. ** ** Kutsuu: kysy_pelaajan_tiedot ** poista_pelaaja ** p_poista_NULL ** Tekij„: Juha Ala-Aho ** Pvm: 10.12.1991 ----------------------------------------------------------------------------*/ { int ind,poistettuja=0; printf("\n\n"); printf("Pelaajan tietojen korjaus\n"); printf("=========================\n"); printf("\n"); printf("Valitse tietojen korjaus tai poisto(K/p):"); if ( odota_nappain("KP",'K',VAIN_ISOT) =='K') { do { printf("\n"); printf("Anna korjattavan pelaajan indeksi"); printf("(luvut v„lilt„ 0-%d) >",sarja_pelaajat->pelaajia-1); scanf("%d",&ind); } while (ind>=sarja_pelaajat->pelaajia); printf("\n"); printf("Korjaa tietoja tarvittaessa!\n"); kysy_pelaajan_tiedot(sarja_pelaajat->pelaajat[ind],PAIVITYS); } else { do { printf("\n"); printf("Anna poistettavan pelaajan indeksi"); printf("(luvut v„lilt„ 0-%d) >",sarja_pelaajat->pelaajia-1); scanf("%d",&ind); } while (ind>=sarja_pelaajat->pelaajia); printf("\n"); if ( !poista_pelaaja(sarja_pelaajat,ind) ) poistettuja++; if ( poistettuja ) p_poista_NULL(sarja_pelaajat); } } /****************************************************************************/ void pelaajat( Pelaajarekisteri_tyyppi *sarja_pelaajat /* pelaajarek jota k„sitell„„n */ ) /* Aliohjelmalla tulostetaan menu josta voidaan valita joko pelaajien lis„ys ** tai pelaajien tietojen korjaus. ** ** Kutsuu: lisaa_uusi_pelaaja ** pelaajan_tietojen_korjailu ** Tekij„: Juha Ala-Aho ** Pvm: 18.12.1991 ----------------------------------------------------------------------------*/ { char nappain; int toista=1; do { printf("\n\n\n"); printf(" K„sitell„„n pelaajia\n"); printf(" ====================\n"); printf("\n"); printf(" Valitse toiminto\n"); printf(" 1 = pelaajien lis„ys\n"); printf(" 2 = pelajien tietojen korjaus\n"); printf("\n :"); nappain = odota_nappain("12",'0',VAIN_ISOT); switch (nappain) { case '0': toista = 0; break; case '1': lisaa_uusi_pelaaja(sarja_pelaajat); break; case '2': pelaajan_tietojen_korjailu(sarja_pelaajat); break; } } while (toista); } static char *P_EI_VOI_LUODA = "Pelaajistolle ei saada varattua tilaa muistista!"; /****************************************************************************/ char /* NULL =onnistui */ *luo_pelaajisto( /* muut = virheilmoitus merkkijonona */ Pelaajarekisteri_tyyppi *sarja_pelaajat,/* t K„sitelt„v„ pelaajarekisteri*/ int koko /* s Pelaajarekisterin maksimipelaajam„„r„.*/ ) /* ** Funktiolla luodaan pelaajarekisteriin osoitintaulukko pelaajistoon. ** Mik„li pelaajistoa ei voida luoda, palautetaan 1. ----------------------------------------------------------------------------*/ { sarja_pelaajat->pelaajat = malloc(koko*(sizeof(Pelaaja_tyyppi *))); sarja_pelaajat->max_pelaajia=koko; sarja_pelaajat->pelaajia=0; if (sarja_pelaajat->pelaajat) return NULL; else return P_EI_VOI_LUODA; }