/****************************************************************************/ /* ** P E L A A T A L . C ** ** Sarjan pelaajien levylt„ lukeminen ja levylle tallettaminen. ** ** Aliohjelmat: ** luo_pelaajarekisteri - kysyy pelaajarekisterin t„ydellisen nimen ja ** alustaa ja luo tarvittavat rakenteet. ** lisaa_pelaaja_rivi - lis„„ uuden pelaajan joka annettu muodossa ** Tikkanen|Esa|121264|hyokkaaja|56|70|126 ** lue_pelaajarekisteri - kysyy pelaajarekisterin nimen ja lukee tiedot ** levylt„ mik„li pelaajarekisteri„ ei l”ydy, ** annetaan mahdollisuus uuden luomiseen ** pelaaja_riviksi - muuttaa pelaajatietueen tiedot muotoon ** Tikkanen|Esa|121264|hyokkaaja|56|70|126 ** talleta_pelaajarekisteri - tallettaa pelaajarekisterin tiedot levylle ** ja muuttaa vanhan tiedoston nimelle .BAK ** p_kopioi_kommentit - kopioi toisen tiedoston kommentit toiseen ** p_mallirivi - tekee mallirivin tallettamista varten ** ** ** Aliohjelmat olettavat pelaajatiedoston olevan seuraavaa muotoa: ** **Liigapelaajat **300 **; Kenttien j„rjestys tiedostossa on seuraava: **; sukunimi |etunimi |syntyma_aika|pelipaikka |numero|joukkue|maalit|syotot|pisteet| **Tikkanen |Esa |121264 |hy”kk„„j„ |11 |TPS |56 |70 |126 | **Tammi |Jukka |080863 |maalivahti |1 |Ilves |0 |1 |1 | **Gudas |Leo |110662 |puolustaja |9 |JypHT |3 |6 |9 | ** ** ** ** Tiedoston alussa olevat kommenttirivit kirjoitetaan talletuksessa ** per„kk„in nimi ja koko -rivin j„lkeen. ** Se kommenttirivi, jolla on erotinmerkki, toimii talletuksen ** yhteydess„ mallirivin„, joka m„„r„„ sarakkeiden leveydet. ** ** ** Tekij„t: Vesa Lappalainen ** Ohjelmointikurssi 1991 ** Tehty: 13.11.1991 ** Muutettu: 17.12.1991/jaa ** Mit„ muutettu: Vastaamaan omaa harjoitusty”t„ ** */ #include #include #include #include "mjonot.h" #include "sarja.h" /* Globaali muuttuja TYHJA_JONO[] m„„ritelty tiedostossa sarjatal.c */ /****************************************************************************/ char /* = Talletuksessa k„ytett„v„ mallirivi. */ *p_mallirivi(void) /* = TYHJA_JONO, mik„li tilaa ei saada varattua. */ /* ** Funktiolla luodaan tilaa mallirivi„ varten ja luodaan mallirivi, ** joka on muotoa ** ;sukunimi |etunimi |syntyma_aika |.... ** ** Globaalit: PKENTAT ** Algoritmi: Lis„t„„n PKENTAT taulukosta aina seuraava kent„n nimi ** ja laitetaan | kent„n mallipituuden p„„h„n. ----------------------------------------------------------------------------*/ { int koko=0,k; char *m; for (k=0; ktiedoston_nimi,P_N_S(sarja_pelaajat->pelaajarekisterin_nimi)); printf("Anna pelaajarekisterin maksimij„senm„„r„>"); lue_kokluku_oletus(MAX_PELAAJIA,&(sarja_pelaajat->max_pelaajia)); sarja_pelaajat->pelaajia=0; sarja_pelaajat->mallirivi=p_mallirivi(); return luo_pelaajisto(sarja_pelaajat,sarja_pelaajat->max_pelaajia); } /****************************************************************************/ int /* */ lisaa_pelaaja_rivi( /* 0 = lis„ys onnistui, 1 = lis„ys ep„onnistui */ Pelaajarekisteri_tyyppi *sarja_pelaajat,/* s,t pelaajarek johon rivi lis„t*/ char *rivi /* s Rivi joka sis„lt„„ lis„tt„v„n tiedot */ ) /* ** Funktiolla lis„t„„n pelaajistoon merkkijonossa rivi oleva pelaaja. ** Pelaajan tiedot t„ytyy olla eroteltuina erotinmerkeill„. ** ** Globaalit: PKENTAT,PKENTTIA ** Muuttuu: *rivi ** Kutsuu: lisaa_pelaaja ** Tekij„: Vesa Lappalainen ** Pvm: 9.11.1991 ** Algoritmi: Luetaan kuhunkin kentt„„n tieto kentt„listan mukaan. ** rivist„ etsit„„n erotinmerkki ja laitetaan sen tilalle ** NUL-merkki. Poistetaan turhat tyhj„t. ** L”ytynyt jono laitetaan oikeaan kentt„„n. ** Riviss„ siirryt„„n erotinmerkki„ seuraavaan paikkaan. ** (strtok ei k„y, koska se hukkaa per„kk„iset erotinmerkit ** joista pit„isi tulla tyhji„ kentti„!) ** Esimerkki: rivi = Tikkanen |Esa |121264|hyokkaaja |... ** pelaaja = Tikkanen,Esa,121264,hyokkaaja... ----------------------------------------------------------------------------*/ { int i,p1=0,p2=0,lr=strlen(rivi); Pelaaja_tyyppi pelaaja; for (i=0; i ** ** Se kommenttirivi (tai viimeinen niist„), joilla esiintyy ** erotinmerkki (esim. |) otetaan tallettamista varten malliriviksi. ** Muuten kommenttirivit unohdetaan. ** Tulostetaan ne rivit, joita ei jostakin syyst„ saada lis„tty„ ** pelaajaluetteloon. ** ** Globaalit: TARKENNIN (vakio jono) ** EROTTIMET (vakio jono) ** Sy”tt”: P„„teelt„, ** tiedostosta ** Tulostus: N„yt”lle ** Kutsuu: f_lue_jono ** P_N_S (makro) ** lue_jono ** luo_pelaajisto ** lisaa_pelaaja_rivi ** Tekij„: Vesa Lappalainen ** Pvm: 9.11.1991 ----------------------------------------------------------------------------*/ { FILE *f; char jono[400],apu[50], *viesti; int vikoja=0; sarja_pelaajat->mallirivi = TYHJA_JONO; sarja_pelaajat->nykypelaaja = 0; sarja_pelaajat->max_pelaajia = MAX_PELAAJIA; sarja_pelaajat->pelaajia = 0; sarja_pelaajat->haku = NULL; do { /* Kysell„„n kunnes tiedosto l”ytyy! */ printf("Anna pelaajarekisterin nimi>"); if ( lue_jono(P_N_S(sarja_pelaajat->tiedoston_nimi)) <= OLETUS ) return NIMEA_EI_ANNETTU; kopioi_jono(P_N_S(jono),sarja_pelaajat->tiedoston_nimi); liita_jono (P_N_S(jono),TARKENNIN); if ( !(f=fopen(jono,"rt")) ) { /* Avaus ei onnistu! Luodaanko? */ printf("pelaajarekisterin %s tietoja ei ole!\n", sarja_pelaajat->tiedoston_nimi); printf("Luodaanko tiedot (K/e):"); if ( kylla_vastaus() ) return luo_pelaajarekisteri(sarja_pelaajat); } /* Avaus ei onnistu! Luodaanko? */ } while (!f); /* Kunnes tiedosto l”ytyy! */ /* Luetaan tiedostosta pelaajarekisterin nimi ja max_koko sek„ luodaan pelaajisto */ if ( f_lue_jono(f,P_N_S(sarja_pelaajat->pelaajarekisterin_nimi))max_pelaajia); if ( (viesti=luo_pelaajisto(sarja_pelaajat,sarja_pelaajat->max_pelaajia))!=NULL ) return viesti; /* Luetaan pelaajisto ja mahd. mallirivi: */ while ( !feof(f) ) { if ( f_lue_jono(f,P_N_S(jono))<=OLETUS ) continue; if ( jono[0]==';' ) { /* Jos kommenttirivi */ if ( strpbrk(jono,EROTTIMET) ) { /* Mallirivi */ if ( sarja_pelaajat->mallirivi != TYHJA_JONO ) free(sarja_pelaajat->mallirivi); sarja_pelaajat->mallirivi = tee_jono(jono); } continue; /* Muuten kommenttirivit unohdetaan. */ } kopioi_jono(P_N_S(apu),jono); /* Jemmataan p„tk„ rivi„ viestiksi! */ if ( lisaa_pelaaja_rivi(sarja_pelaajat,jono) ) { printf("*** Ei saada lis„tty„: %s ***\n",apu); vikoja++; } } /* Jos tee_jono ep„onnistui, laitetaan jokin mallirivi */ if (!sarja_pelaajat->mallirivi) sarja_pelaajat->mallirivi = TYHJA_JONO; fclose(f); if (vikoja) { printf("%d pelaajaa j„i lis„„m„tt„!\n",vikoja); odota_jotakin(); } return NULL; } /****************************************************************************/ int /* */ pelaaja_riviksi( /* 0 = onnistuu 1 = ei onnistu */ Pelaaja_tyyppi *pelaaja ,/* s Pelaaja joka muutetaan */ char *malli ,/* s Mallirivi, josta otetaan pituudet */ char *rivi ,/* t Rivi jonne pelaaja muutetaan */ int max_pit /* s Rivin maksimipituus */ ) /* ** Funktiolla muutetaan pelaaja yhdeksi riviksi, jossa kent„t on erotettu ** toisistaan mallirivist„ l”ytyvill„ erotinmerkeill„. Mik„li malliriviss„ ** on v„hemm„n tilaa, kuin tarvitaan, k„ytet„„n tarvittava m„„r„ tilaa. ** Mik„li mallirivi on tyhj„, pakataan tiedot niin ahtaalle kuin mahdollista. ** ** Globaalit: PKENTAT ** EROTTIMET ** Algoritmi: Mallirivist„ etsit„„n erotinmerkkej„. Aina kun erotinmerkki ** l”ytyy, laitetaan tulosriviin kentt„listan mukaisesti seuraava ** kentt„ ja riitt„v„sti tyhji„, jotta erotin merkki saadaan ** samalle paikalle. Sitten laitetaan erotinmerkki. Mik„li ** mallirivin erotinmerkit loppuu ennen kentt„listaa, k„ytet„„n ** edellist„ erotinmerkki„ jotta koko kentt„lista saadaan ** muutetuksi. ** Esimerkki: malli = "sukunimi |etunimi |syntyma_aika| ..." ** pelaaja = Tikkanen,Esa,121264,hyokkaaja... ** rivi = Tikkanen |Esa |121264|hyokkaaja ----------------------------------------------------------------------------*/ { char erotin; int mi=0,ri=0; /* Indeksi mallissa ja riviss„ */ int lm=strlen(malli); int i; rivi[0] = 0; /* Tyhjennet„„n tulosjono. */ erotin = EROTTIMET[0]; for (i=0; i= max_pit-1 ) return 1; /* Jos rivist„ tuli liian pitk„ -> */ for (;(ritiedoston_nimi); liita_jono (P_N_S(bak_nimi),VANHATARK); kopioi_jono(P_N_S(jono) ,sarja_pelaajat->tiedoston_nimi); liita_jono (P_N_S(jono) ,TARKENNIN); remove(bak_nimi); /* Vanha .BAK t„ytyy poistaa jotta rename toimii */ vanhat_tallessa = !rename(jono,bak_nimi); if ( !(f = fopen(jono,"wt") ) ) return EI_AUKEA_K; if ( fprintf(f,"%s\n",sarja_pelaajat->pelaajarekisterin_nimi)==EOF ) return EI_TALLETU; if ( fprintf(f,"%d\n",sarja_pelaajat->max_pelaajia)==EOF ) return EI_TALLETU; if ( p_kopioi_kommentit(f,bak_nimi) ) { /* Jos ei kopioidu, laitetaan olet. */ if ( fprintf(f,"; Kenttien j„rjestys tiedostossa on seuraava:\n")==EOF ) return EI_TALLETU; if ( fprintf(f,"%s\n",sarja_pelaajat->mallirivi)==EOF ) return EI_TALLETU; } for (i=0; ipelaajia; i++) { pelaaja_riviksi(sarja_pelaajat->pelaajat[i],sarja_pelaajat->mallirivi, P_N_S(jono)); if ( fprintf(f,"%s\n",jono)==EOF ) return EI_TALLETU; } fclose(f); printf("\n"); printf("Pelaajien tiedot talletettu tiedostoon %s%s\n", sarja_pelaajat->tiedoston_nimi,TARKENNIN); if (vanhat_tallessa) printf("Pelaajien vanhat tiedot tiedostossa %s%s\n", sarja_pelaajat->tiedoston_nimi,VANHATARK); return NULL; }