/****************************************************************************/ /* ** K E R H O T A L . C ** ** Kerhon tietojen levylt„ lukeminen ja levylle tallettaminen. ** ** Aliohjelmat: ** luo_kerho - kysyy kerhon t„ydellisen nimen ja alustaa ** ja luo tarvittavat rakenteet. ** lisaa_jasen_rivi - lis„„ uuden j„sen joka annettu muodossa ** Ankka Aku|12234-34|... ** lue_kerho - kysyy kerhon nimen ja lukee tiedot levylt„ ** mik„li kerhoa ei l”ydy, annetaan mahdollisuus ** uuden luomiseen ** jasen_riviksi - muuttuu j„sentietueen tiedot muotoon ** Ankka Aku|12234-34|... ** talleta_kerho - tallettaa kerhon tiedot levylle ** ja muuttaa vanhan tiedoston nimelle .BAK ** kopioi_kommentit - kopioi toisen tiedoston kommentit toiseen ** ** ** Aliohjelmat olettavat tiedoston olevan seuraavaa muotoa: ** **Kelmien kerho ry **50 **; Kenttien j„rjestys tiedostossa on seuraava: **; sukunimi etunimet|sotu |katuosoite |postinumero|postiosoite|kotipuh... **;---------------------------------------------------------------------------... **Ankka Aku |010245-123U|Ankkakuja 6 |12345 |ANKKALINNA |12-1232... **Susi Sepe |020347-123T| |12555 |Per„mets„ | ... **Ponteva Veli |030455-3333| |12555 |Per„mets„ | ... ** ** ** 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: 20.12.1991 ** Muutettu: 25.12.1991 ** Mit„ muutettu: Riippuvuus kenttien nimist„ poistettu. ** K„sitell„„n lippua kerho->muutettu ** eli ei esim. talleteta jollei muutoksia. ** Mallirivin k„sittely. ** Kommenttien kopiointi ** ** */ #include #include #include #include "mjonot.h" #include "kerho.h" /****************************************************************************/ int /* */ kopioi_kommentit( /* 0 = onnistui, 1 = ei onnistunut */ FILE *f ,/* s Tiedosto jonne kopioidaan */ char *mista ,/* s Tiedoston nimi joka kopioidaan */ Kerho_tyyppi *kerho /* s Kerho, josta otetaan tarvittaessa mallirivi*/ ) /* ** Funktiolla kopioidaan toisessa tiedostossa olevat kommentit tiedostoon f. ** My”s tyhj„t rivit tulkitaan kommenteiksi. ** ** Algoritmi: Luetaan tiedostoa kunnes kommentit alkavat ja lopetetaan ** lukeminen kun ne loppuvat. ----------------------------------------------------------------------------*/ { char rivi[400]; FILE *fm; int i, paluu = 1, kommentteja=0; if ( !(fm=fopen(mista,"rt")) ) goto sulje; while ( !feof(fm) ) { if ( f_lue_jono(fm,N_S(rivi)) < OLETUS ) goto sulje; if ( (!rivi[0]) || (rivi[0]==';') ) { kommentteja++; if ( fprintf(f,"%s\n",rivi)==EOF ) goto sulje; } else if (kommentteja) break; } if (kommentteja) paluu=0; sulje: fclose(fm); if (!paluu) return 0; /* Jollei saatu kommentteja toisesta tiedostosta, tehd„„n ne itse */ if ( fprintf(f,"; Kenttien j„rjestys tiedostossa on seuraava:\n")==EOF ) return 1; if ( fprintf(f,"%s\n",kerho->mallirivi)==EOF ) return 1; /* Talletetaan viiva */ if ( fprintf(f,";")==EOF ) return 1; for (i=1; imallirivi); i++) if ( fprintf(f,"-")==EOF ) return 1; if ( fprintf(f,"\n")==EOF ) return 1; return 0; } /****************************************************************************/ char /* NULL = onnistui */ *luo_kerho( /* muut = virheilmoitus merkkijonona */ Kerho_tyyppi *kerho /* s Luotava kerho */ ) /* ** Funktiolla tehd„„n uuden kerhon luomisessa tarvittavat toimenpiteet. ** ** Sy”tt”: P„„tteelt„ ** Tulostus: N„ytt””n ** Kutsuu: lue_jono_oletus ** lue_kokluku_oletus ** luo_jasentaulukko ----------------------------------------------------------------------------*/ { printf("\n"); lue_jono_oletus("Anna kerhon koko nimi ",0,0, kerho->tiedoston_nimi,N_S(kerho->kerhon_nimi)); printf("Anna kerhon maksimij„senm„„r„>"); lue_kokluku_oletus(MAX_JASENIA,&(kerho->max_jasenia)); kerho->jasenia=0; kerho->mallirivi=mallirivi(); kerho->muutettu = 1; return luo_jasentaulukko(kerho,kerho->max_jasenia); } /****************************************************************************/ int /* */ lisaa_jasen_rivi( /* 0 = lis„ys onnistui, 1 = lis„ys ep„onnistui */ Kerho_tyyppi *kerho ,/* s,t Kerho johon rivi lis„t„„n */ char *rivi /* s Rivi joka sis„lt„„ lis„tt„v„n tiedot */ ) /* ** Funktiolla lis„t„„n j„senist””n merkkijonossa rivi oleva j„sen. ** J„senen tiedot t„ytyy olla eroteltuina erotinmerkeill„. ** ** Globaalit: KENTAT,KENTTIA ** Muuttuu: *rivi ** Kutsuu: kopioi_jono ** poista_tyhjat ** palanen ** lisaa_jasen ** Esimerkki: rivi = Ankka Aku |010245-123U|Ankkakuja 6 |12345|... ** jasen = Ankka Aku,010245-123U,Ankkakuja 6,12345... ----------------------------------------------------------------------------*/ { char *m; int j,k; Jasen_tyyppi jasen; m = rivi; for (k=0; k ** ** 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„ ** j„senluetteloon. ** ** Globaalit: TARKENNIN (vakio jono) ** EROTTIMET (vakio jono) ** Sy”tt”: P„„teelt„, ** tiedostosta ** Tulostus: N„yt”lle ** Kutsuu: f_lue_jono ** N_S (makro) ** lue_jono ** luo_jasentaulukko ** lisaa_jasen_rivi ----------------------------------------------------------------------------*/ { #define PALAUTA(sanoma) {paluu_viesti = sanoma; goto sulje;} FILE *f; char jono[400],apu[50], *viesti, *paluu_viesti = NULL; int vikoja=0; kerho->nykyjasen = 0; kerho->max_jasenia = MAX_JASENIA; kerho->jasenia = 0; kerho->muutettu = 0; kerho->mallirivi = NULL; do { /* Kysell„„n kunnes tiedosto l”ytyy! */ printf("Anna kerhon nimi>"); if ( lue_jono(N_S(kerho->tiedoston_nimi)) <= OLETUS ) return NIMEA_EI_ANNETTU; kopioi_jono(N_S(jono),kerho->tiedoston_nimi); liita_jono (N_S(jono),TARKENNIN); if ( !(f=fopen(jono,"rt")) ) { /* Avaus ei onnistu! Luodaanko? */ printf("Kerhon %s tietoja ei ole!\n",kerho->tiedoston_nimi); printf("Luodaanko tiedot (K/e):"); if ( kylla_vastaus() ) return luo_kerho(kerho); } /* Avaus ei onnistu! Luodaanko? */ } while (!f); /* Kunnes tiedosto l”ytyy! */ /* Luetaan tiedostosta kerhon nimi ja max_koko sek„ luodaan j„senist” */ if ( f_lue_jono(f,N_S(kerho->kerhon_nimi))max_jasenia); if ( (viesti=luo_jasentaulukko(kerho,kerho->max_jasenia))!=NULL ) PALAUTA(viesti); /* Luetaan j„senist”: */ while ( !feof(f) ) { if ( f_lue_jono(f,N_S(jono))<=OLETUS ) continue; if ( jono[0]==';' ) { /* Jos kommenttirivi */ if ( strpbrk(jono,EROTTIMET) ) { /* Mallirivi */ if ( kerho->mallirivi ) free(kerho->mallirivi); kerho->mallirivi = tee_jono(jono); } continue; /* Muuten kommenttirivit unohdetaan. */ } kopioi_jono(N_S(apu),jono); /* Jemmataan p„tk„ rivi„ viestiksi! */ if ( lisaa_jasen_rivi(kerho,jono) ) { printf("*** Ei saada lis„tty„: %s ***\n",apu); vikoja++; } } sulje: /* Jos tee_jono ep„onnistui, laitetaan jokin mallirivi */ if (!kerho->mallirivi) kerho->mallirivi = mallirivi(); fclose(f); if (vikoja) { printf("%d nime„ j„i lis„„m„tt„!\n",vikoja); odota_jotakin(); } return paluu_viesti; #undef PALAUTA } /****************************************************************************/ int /* */ jasen_riviksi( /* 0 = onnistuu 1 = ei onnistu */ Jasen_tyyppi *jasen ,/* s J„sen joka muutetaan */ char *malli ,/* s Mallirivi, josta otetaan pituudet */ char *rivi ,/* t Rivi jonne j„sen muutetaan */ int max_pit /* s Rivin maksimipituus */ ) /* ** Funktiolla muutetaan j„sen 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: KENTAT ** 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 = "nimi |sotu |Katuosoite | ..." ** jasen = Ankka Aku,010245-123U,Ankkakuja 6,12345... ** rivi = Ankka Aku |010245-123U|Ankkakuja 6 |12345 ----------------------------------------------------------------------------*/ { char erotin; int mi=0,ri=0; /* Indeksi mallissa ja riviss„ */ int lm=strlen(malli); int k; rivi[0] = 0; /* Tyhjennet„„n tulosjono. */ erotin = EROTTIMET[0]; for (k=0; k= max_pit-1 ) return 1; /* Jos rivist„ tuli liian pitk„ -> */ for (;(rimuutettu ) return NULL; kopioi_jono(N_S(bak_nimi),kerho->tiedoston_nimi); liita_jono (N_S(bak_nimi),VANHATARK); kopioi_jono(N_S(jono) ,kerho->tiedoston_nimi); liita_jono (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",kerho->kerhon_nimi)==EOF ) PALAUTA(EI_TALLETU); if ( fprintf(f,"%d\n",kerho->max_jasenia)==EOF ) PALAUTA(EI_TALLETU); if ( kopioi_kommentit(f,bak_nimi,kerho) ) PALAUTA(EI_TALLETU); for (i=0; ijasenia; i++) { jasen_riviksi(kerho->jasenet[i],kerho->mallirivi,N_S(jono)); if ( fprintf(f,"%s\n",jono)==EOF ) PALAUTA(EI_TALLETU); } sulje: fclose(f); printf("\n"); printf("Tiedot talletettu tiedostoon %s%s\n",kerho->tiedoston_nimi,TARKENNIN); if (vanhat_tallessa) printf("Vanhat tiedot tiedostossa %s%s\n",kerho->tiedoston_nimi,VANHATARK); return paluu; #undef PALAUTA }