/****************************************************************************/ /* ** K E R H O R A K . C ** ** Kerhon rakenteeseen oleellisesti liittyvi„ aliohjelmia ** ** Aliohjelmat: ** alusta_kerho - alustaa tietorakenteen kerhoksi ** mallirivi - tekee mallirivin tallettamista varten ** kent„n indeksi - palauttaa annetun nimisen kent„n indeksin ** kentan_tyyppi - palauttaa kent„n tyypin ** kentan_osoite - palauttaa kent„n osoitteen ** kentan_koko - palauttaa kent„n koon tavuina ** kentta_jonoksi - palauttaa valitun kent„n merkkijonona ** kentta_tjonoksi - kuten edell„, mutta talletusta varten ** jono_kentaksi - muuttaa merkkijonon kent„ksi ** tulosta_jasen - tulostaa j„senen valittuun tiedostoon ** poista_NULL - poistaa osoitintaulukosta NULL-osoittimet ** tulosta_kenttalista - tulostaa valittavaksi kaikki j„sentietueen ** kent„t ** alusta_jasen - alustaa j„senen ** lisaa_jasen - lis„„ uuden j„senen rakenteeseen ** luo_jasentaulukko - luo j„senosoitintaulukon ** kysy_kentta - kysyy j„senen valitun kent„n tiedot ** kysy_jasenen_tiedot - kysyy j„senen kaikkien kenttien tiedot ** kysy_yksi_kentta - kysyy yhden kent„n tiedot ** poista_jasen - varmistaa ja poistaa valitun j„senen ** kysy_haku - kysyy yhden hakukent„n arvon ** kysy_hakutiedot - kysyy koko hakutaulukon tiedot ** sijoita_kentta - sijoittaa yhden kent„n j„senest„ toiseen ** ** ** Yleinen tietorakenne on seuraava: ** ** ** Kerho_tyyppi Haku_tyyppi Jasen_tyyppi Rakenne_tyyppi ** ------ ------- ** | | | | ------- ** | 7 | |--->| | |-------------------------------->| | ** | 3 | | | | | | | 0 ** | | | ------- | |------------------>| | ** | | | | | ------- ** | o--+----| |---- ------ | | | ** | | | | o--+---- |------------>| | 1 ** | o--+----------------| |---->| | | |--->| | ** | | jasenet | | | ------ | | ------- ** | o--+------>|-----| | ------ | o--+-- | | | ** ------ | o--+-----| | | | | | 2 ** |-----| |----->| | | | | ** | o--+------------| ------ ------ | ------- ** |-----| | o--+-- | | ** | o--+--------------------------->| | | | 3 ** |-----| | | | | ** | o--+--? ------ ------- ** |-----| | | ** | o--+--? | | 4 ** |-----| | | ** | o--+--? ------- ** |-----| | | ** | o--+--? | | 5 ** |-----| | | ** ------- ** ** ** 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 ** Muutettu: 24.12.1991/vl ** Mit„ muutettu: Lis„tty etsimisess„ ja selailussa tarvittavia osia. ** Muutettu: 26.12.1991/vl ** Mit„ muutettu: Kentt„taulukkoon perustuva muuttuva rakenne ** Muutettu: 28.12.1991/vl ** Mit„ muutettu: Yleisempi tietorakenne ** Muutettu: 4.12.1991/vl ** Mit„ muutettu: kysy_yksi_kentta - lis„tty yksi parametri ** Muutettu: 20.12.1993/vl ** tyhjenna_lisayksessa -> alustus ** paljon muita muutoksia, ks kerho.c ** Muutettu: 29.1.1994/vl ** hakuehtoihin (tyyli SYOTTO) sallitaan my”s ** rajoja toteuttamaton ehto (muuten * eiv„t kelpaa) ** Muutettu: 1.2.1994 ** Mit„ muutettu: Poistetun tallettaminen ** Poistossa muutetaan muutettu-lippua ** (ennen ei tallettanut tiedostoa!) ** ** */ #include #include #include #include #include "mjonot.h" #include "kerho.h" #include "help.h" #define OLET_ALKU 19 /* Oletuksen alkusarake */ #define VAKANEN 33 /* V„k„sen alkusarake */ #define K_A(nimi) sizeof(((Jasen_tyyppi *)0)->nimi),\ offsetof(Jasen_tyyppi,nimi) /* ** K_A(nimi) ** Makro muuttaa Jasentyyppisen tietueen kent„n nimen ** kent„n kooksi ja alkupaikaksi tietueen alusta lukien. */ /* ** Taulukko, johon on ker„tty 'intiimit' tiedot kustakin Jasentietueen ** kent„st„. T„m„n taulukon avulla tietueen kaikkia kentti„ pystyt„„n ** sitten k„ytt„m„„n silmukassa: */ static Kentta_tyyppi KERHO_KENTAT[] = { {"J„senen nimi" ,"nimi" ,K_A(nimi) ,TYHJENNA_JONO,19,Tjono ,"%s",t_nimi}, {"Sotu" ,"sotu" ,K_A(sotu) ,TYHJENNA_JONO,11,Tsotu ,"%s",t_sotu}, {"Katuosoite" ,"katuosoite" ,K_A(katuosoite) ,"" ,15,Tjono ,"%s",t_katu}, {"Postinumero" ,"postinumero" ,K_A(postinumero) ,"" ,05,Tjono ,"%s",t_numeerinen}, {"Postiosoite" ,"postiosoite" ,K_A(postiosoite) ,"" ,15,Tjono ,"%s",t_isoksi}, {"Kotipuhelin" ,"kotipuhelin" ,K_A(kotipuhelin) ,"" ,11,Tjono ,"%s",t_puh}, {"Ty”puhelin" ,"ty”puhelin" ,K_A(tyopuhelin) ,TYHJENNA_JONO,11,Tjono ,"%s",t_puh}, {"Autopuhelin" ,"autopuhelin" ,K_A(autopuhelin) ,TYHJENNA_JONO,11,Tjono ,"%s",t_puh}, {"Liittymisvuosi" ,"liittymisvuosi",K_A(liittymisvuosi),"" ,04,Tint ,"%d",t_vuosi_1900}, {"J„senmaksu mk" ,"j„senmaksu" ,K_A(jmaksu) ,"" ,06,Tdouble,"%6.2lf",t_ok}, {"Maksettu maksu mk","maksettu maksu",K_A(maksu) ,"" ,06,Tdouble,"%6.2lf",t_ok}, {"Lis„tietoja" ,"lis„tietoja" ,K_A(lisatietoja) ,TYHJENNA_JONO,30,Tjono ,"%s",t_ok} }; #undef K_A static char KERHO_KENTTAVALINNAT[50] = "123456789ABCDEFGHIJ ?+-" NAP_KORJ_POISTO NAP_JA_TAI; static char *KERHO_MALLITULOSTUS[] = { /*Kullekin kent„lle tulostusmuoto: */ " %s" , " %s\n" , /* nimi ja sotu */ " %s" , " %s" , " %s\n" , /* katu, postinro, postios */ " k: %s" , " t: %s" , " a: %s\n" , /* puhelimet */ " Liittynyt %s." , " J„senmaksu %s mk." , " Maksettu %s mk\n" , /* Liittymisvuosi ja maksut */ " %s\n" }; #define K_KENTAT kerho->rakenne->kentat #define K_KOKO (kerho->rakenne->koko) #define J_KENTTIA (jasen->rakenne->kenttia) #define J_KENTAT jasen->rakenne->kentat #define J_KOKO (jasen->rakenne->koko) /****************************************************************************/ void /* */ alusta_kerho( /* */ Kerho_tyyppi *kerho /* t Alustetaan kerhon tietorakenne */ ) /* ** Aliohjelmalla alustetaan kerhon tietorakenne. ** ** Globaalit KERHO_KENTTIA, KERHO_KENTTAVALINNAT, KERHO_MALLITULOSTUS ----------------------------------------------------------------------------*/ { int kenttia,k,s_ind; kerho->rakenne = calloc(1,sizeof(Rakenne_tyyppi)); if ( !kerho->rakenne ) { printf("Muistia ei saada varattua! Ei voida jatkaa!\n"); exit(1); } kerho->tiedoston_nimi[0] = 0; kerho->rakenne->kentat = KERHO_KENTAT; kerho->rakenne->mallitulostus = KERHO_MALLITULOSTUS; kerho->rakenne->kenttavalinnat = KERHO_KENTTAVALINNAT; kenttia = sizeof(KERHO_KENTAT)/sizeof(Kentta_tyyppi); kerho->rakenne->kenttia = kenttia; kerho->rakenne->kenttavalinnat[kenttia] = 0; kerho->rakenne->mallirivi = NULL; kerho->rakenne->tiedoston_nimi = ""; kerho->rakenne->kommentti = "; Kerhon rakenne"; kerho->rakenne->rak_nro = 0; kopioi_jono(N_S(kerho->rakenne->nimi),"kerho"); kerho->rakenne->paamenu = "\n\n\n\n\n" "J„senrekisteri\n" "==============\n" "\n" "Kerhossa %s on %d j„sent„.\n" "\n" "Valitse:\n" " ? = avustus\n" " 0 = lopetus\n" " 1 = lis„„ uusi j„sen\n" " 2 = etsi j„senen tiedot\n" " 3 = tulosteet\n" " 4 = tietojen korjailu\n" " 5 = p„ivit„ j„senmaksuja\n" " 6 = asetukset\n" " :"; kerho->rakenne->menu_valinnat = "?0123456"; kerho->rakenne->lisays_otsikko = "\n" "J„seni„ on nyt %d.\n" "Anna uusi nimi muodossa sukunimi etunimi etunimi\n"; kerho->rakenne->olet_alku = OLET_ALKU; kerho->rakenne->vakanen = VAKANEN; s_ind = 0; /* Viimeisen kent„n (suurin alku) indeksi */ for (k=1; kKERHO_KENTAT[s_ind].alku) s_ind = k; kerho->rakenne->koko = KERHO_KENTAT[s_ind].alku+KERHO_KENTAT[s_ind].koko; } /****************************************************************************/ char /* = "" mik„li tilaa ei saada varattua. */ *mallirivi( /* = Talletuksessa k„ytett„v„ mallirivi. */ Rakenne_tyyppi *rakenne /* s Rakenne, josta mallirivi tehd„„n. */ ) /* ** Funktiolla luodaan tilaa mallirivi„ varten ja luodaan mallirivi, ** joka on muotoa ** ;nimi |sotu |katuosoite |.... ** ** Algoritmi: Lis„t„„n KENTAT taulukosta aina seuraava kent„n nimi ** ja laitetaan | kent„n mallipituuden p„„h„n. ----------------------------------------------------------------------------*/ { int koko=0,k; char *m; for (k=0; kkenttia; k++) koko += rakenne->kentat[k].mpit; koko += rakenne->kenttia+1; /* Lis„t„„n viel„ erotinmerkin viem„ tila */ if ( !(m=malloc(koko)) ) return ";"; memset(m,' ',koko-1); /* T„ytet„„n jono tyhjill„ */ m[0] = ';'; m[1] = 0; koko=0; for (k=0; kkenttia; k++) { koko += rakenne->kentat[k].mpit; liita_jono(m,koko+1,rakenne->kentat[k].nimi); m[strlen(m)]=' '; m[koko++]=EROTTIMET[0]; m[koko] =0; } return m; } /****************************************************************************/ int /* -1 = ei l”ydy */ kentan_indeksi( /* muut = kent„n indeksi */ Jasen_tyyppi *jasen ,/* s J„sen, josta kent„n nime„ etsit„„n. */ char *nimi /* s Kent„n nimi, jota etsit„„n. */ ) /* ** Funktiolla plautetaan annettua kent„n nime„ vastaava indeksi. ** ----------------------------------------------------------------------------*/ { int k; for (k=0; krakenne->kas_kentat[TULOSTUS]; if ( tarkista_kas_kentat(jasen->rakenne,TULOSTUS) ) return; for (k = 0; kk[k]; k++) { kn = paikka(jasen->rakenne->kenttavalinnat,kk[k]); if ( kn < 0 ) continue; kopioi_jono(N_S(mt),jasen->rakenne->mallitulostus[kn]); if ( mt[0] == 0 ) continue; if ( jasen->rakenne->poista_cr ) poista_merkit(mt,"\n\r"); fprintf(f,mt,kentta_jonoksi(kn,jasen)); cr = ( mt[strlen(mt)-1] == '\n' ); } if ( !cr ) fprintf(f,"\n"); } /****************************************************************************/ int /* */ poista_NULL( /* 0 = poisto onnistui, 1 = ep„onnistui */ Kerho_tyyppi *kerho /* s Kerho josta NULL-osoittimet poistetaan. */ ) /* ** Funktiolla poistetaan NULL osoittimet listasta. ** ** Algoritmi: Lukuosoitin ja kirjoitusosoitin, joiden v„limatkaa ** kasvatetaan aina, kun l”ytyy poistettava. ----------------------------------------------------------------------------*/ { int j,k=0; for (j=0; jjasenia; j++) if ( kerho->jasenet[j] ) kerho->jasenet[k++] = kerho->jasenet[j]; kerho->jasenia = k; kerho->nykyjasen = 0; return 0; } /****************************************************************************/ void /* */ tulosta_kenttalista( /* */ Kerho_tyyppi *kerho, /* s Kerho, jonka kentt„lista tulostetaan. */ 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. ** Tarvittaessa tulostetaan useaan palstaan (mist„ kaikki sotku, muuten ** homma olisikin vain yksi for-silmukka). ** ** Tulostus: N„ytt””n ** Kutsuu: ----------------------------------------------------------------------------*/ { int r,k,p,palstoja=K_KENTTIA/20+1,ppit=(1.0*K_KENTTIA/palstoja)+0.9; viiva(); for (k=0; k= K_KENTTIA ) break; if (strchr(lista,kerho->rakenne->kenttavalinnat[k+p*ppit])) r++; } for (p=0; p= K_KENTTIA ) break; if (strchr(lista,kerho->rakenne->kenttavalinnat[k+p*ppit])) printf(" %c = %-13s", kerho->rakenne->kenttavalinnat[k+p*ppit],K_KENTAT[k+p*ppit].nimi); else if ( r ) printf(" %c = %-13s",' ',""); } if ( r ) printf("\n"); } if ( strchr(lista,NAP_JA) ) printf(" %c = %s\n",NAP_JA,"JA ehto kaikille kentille"); if ( strchr(lista,NAP_TAI) ) printf(" %c = %s\n",NAP_TAI,"TAI ehto kaikille kentille"); printf(" "); } /****************************************************************************/ 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! ** ** Kutsuu: jono_kentaksi ----------------------------------------------------------------------------*/ { int k, tyhjenna_kaikki=0; char *alustus; jasen->rakenne = kerho->rakenne; if ( kerho->nykyjasen >= kerho->jasenia || kerho->rakenne != kerho->jasenet[kerho->nykyjasen]->rakenne ) tyhjenna_kaikki=1; else memcpy(jasen,kerho->jasenet[kerho->nykyjasen],K_KOKO); for (k=0; kjasenia >= 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(J_KOKO); if ( uusi_jasen==NULL ) return 1; memcpy(uusi_jasen,jasen,J_KOKO); 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; kerho->haku=NULL; 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 */ Jasen_tyyppi *jasen, /* J„sen, jolle viesti tulostetaan. */ int nro /* Kent„n numero, jonka viesti halutaan. */ ) /* ** Funktiolla palautetaan haluttua kentt„„ vastaava kent„n kysymisess„ ** tarvittava viesti. ** ----------------------------------------------------------------------------*/ { if ( nro<0 || J_KENTTIA<=nro ) return ""; return J_KENTAT[nro].hopute; } /****************************************************************************/ static int on_rakenteen_vaihto( int nro ,/* s Luettavan kent„n numero */ char *jono ,/* t Jono johon kent„n vastaus luetaan. */ Tarkistus_funktio *f ,/* s Funktio, jolla jonon oikeellisuus tark. */ Tarkistus_tyyppi *tark ,/* s Tarkistusfunktion parametri */ char *apu, int apun ) /* Tutkitaan onko kyseess„ rakenteenvaihtok„sky */ { Rakenne_tyyppi *rakenne; if ( jokujono(apu,VAIHDA_RAK) != 0 ) return 0; if ( nro != 0 || tark->syotto_tyyppi != LISAYS ) { printf("Rakenteen voi muuttaa vain lis„yksen 1. kent„ss„!\n"); kopioi_jono(apu,apun,jono); return 1; } rakenne = kysy_rakenne(); apu[0] = 0; if ( rakenne == NULL || rakenne == tark->jasen->rakenne ) return 1; tark->kerho->rakenne = rakenne; alusta_jasen(tark->kerho,tark->jasen); *f = tark->kerho->rakenne->kentat[nro].tark_fun; return 1; } /****************************************************************************/ static int on_kysy_avustus( char *jono ,/* t Jono johon kent„n vastaus luetaan. */ Tarkistus_funktio f ,/* s Funktio, jolla jonon oikeellisuus tark. */ Tarkistus_tyyppi *tark ,/* s Tarkistusfunktion parametri */ char *apu, int apun ) /* Tutkitaan onko avustus? 0 = ei, 1 = juu */ { if ( jokujono(apu,HELP_JONO) != 0 ) return 0; /* Avustus ? */ alusta_help_rivit(); help_aihe(tarkistus_nimi(f)); help(" Jos haluat takaisin p„„valintaan, paina "POIS"[RETURN].\n"); help(" Jos haluat suluissa olevan arvon, paina [RETURN].\n"); help(" Jos haluat lopuille kentille oletusarvot, paina "LOPUT_OLETUS"[RETURN].\n"); help(" Edell„ mahd | tarkoittaa TAI. Esimerksi .|, \n"); help(" tarkoittaa: paina joko . tai paina ,\n"); help("\n"); help_aihe(tark->aihe); if ( tark->jasen->rakenne->kentat[tark->kentta].rajat[0] ) { help_aihe("Ehto"); help(" Ehto: "); help(tark->jasen->rakenne->kentat[tark->kentta].rajat); help("\n"); } kopioi_jono(apu,apun,jono); return 1; } /****************************************************************************/ int /* 1 = lopetetaan sy”tt” */ kysy_kentta( /* 0 = OK */ /*-1 = loppuihin oletus */ 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[MAX_RIVI]; Tarkistus_tulos_tyyppi f_paluu=TARK_PAL_OLET; int paluu; tark->kentta = nro; kopioi_jono(N_S(apu),jono); do { paluu = lue_jono_oletus(viesti(tark->jasen,nro), tark->jasen->rakenne->olet_alku,tark->jasen->rakenne->vakanen, apu,N_S(apu)); if ( paluu < OLETUS ) return 1; poista_tyhjat(apu); if ( jokujono(apu,POIS) == 0 ) return 1; if ( jokujono(apu,LOPUT_OLETUS) == 0 ) return -1; if ( on_rakenteen_vaihto(nro,jono,&f,tark,N_S(apu)) ) continue; if ( on_kysy_avustus(jono,f,tark,N_S(apu)) ) continue; if (!f) break; /* Jollei tarkistusfunktiota, niin kaikki kelpaa! */ if ( ( tark->syotto_tyyppi != SYOTTO ) && onko_rajoissa(tark->jasen,apu,nro) ) { kopioi_jono(N_S(apu),jono); f_paluu = TARK_PAL_OLET; printf("Ei t„sm„„ ehtoon: %s\n", tark->jasen->rakenne->kentat[nro].rajat); continue; } 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 ** kentta_jonoksi, jono_kentaksi ----------------------------------------------------------------------------*/ { Jasen_tyyppi apu_jasen; Tarkistus_tyyppi tarkistus; char st[MAX_RIVI]; int k=0,kn=0; char *kk; int paluu; tarkistus.kerho = kerho; tarkistus.syotto_tyyppi = kysymys_tyyppi; tarkistus.jasen = &apu_jasen; kopioi_jono(N_S(tarkistus.aihe),""); memcpy(&apu_jasen,jasen,J_KOKO); if ( tarkista_kas_kentat(apu_jasen.rakenne,kysymys_tyyppi) ) return 1; kk = apu_jasen.rakenne->kas_kentat[kysymys_tyyppi]; k = 0; while ( k < strlen(kk) ) { tarkista_kas_kentat(apu_jasen.rakenne,kysymys_tyyppi); tarkistus.seuraava_kentta = k+1; kn = paikka(jasen->rakenne->kenttavalinnat,kk[k]); if ( kn < 0 ) { k++; continue; } kopioi_jono(N_S(st),kentta_jonoksi(kn,&apu_jasen)); paluu = kysy_kentta(kn,N_S(st),apu_jasen.rakenne->kentat[kn].tark_fun, &tarkistus); if ( paluu == 1 ) return 1; if ( paluu == -1 ) break; jono_kentaksi(kn,&apu_jasen,st); k = tarkistus.seuraava_kentta; } if ( strcmp(kentta_jonoksi(0,&apu_jasen),"") == 0 ) return 1; if ( memcmp(jasen,&apu_jasen,J_KOKO) ) { kerho->muutettu = 1; memcpy(jasen,&apu_jasen,apu_jasen.rakenne->koko); } return 0; } /****************************************************************************/ int /* 0 = hommat OK */ kysy_yksi_kentta( /* 1 = halutaan pois kysymyksest„ */ /*-1 = loppuihin oletus */ Kerho_tyyppi *kerho ,/* s Kerho johon j„sent„ kysyt„„n */ Jasen_tyyppi *jasen ,/* s,t T„ytett„v„n j„senen tiedot */ int kentta ,/* s Kentt„, joka kysyt„„n. */ int tark ,/* s Tuleeko tarkistus vai ei */ char *aihe /* s Avustuksen aiheen otsikko */ ) /* ** Funktiolla kysyt„„n yhden kent„n 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„. ** Ei muuta kerhon muutettu-lippua! ** ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_kentta ** kentta_jonoksi, jono_kentaksi ----------------------------------------------------------------------------*/ { Jasen_tyyppi apu_jasen; Tarkistus_tyyppi tarkistus; char st[MAX_RIVI]; int paluu; tarkistus.kerho = kerho; tarkistus.syotto_tyyppi = PAIVITYS; tarkistus.jasen = &apu_jasen; kopioi_jono(N_S(tarkistus.aihe),aihe); memcpy(&apu_jasen,jasen,J_KOKO); tarkistus.seuraava_kentta = kentta+1; kopioi_jono(N_S(st),kentta_jonoksi(kentta,&apu_jasen)); paluu = kysy_kentta(kentta,N_S(st), tark ? apu_jasen.rakenne->kentat[kentta].tark_fun : t_ok, &tarkistus); if ( paluu == 1 ) return 1; if ( paluu == 0 ) jono_kentaksi(kentta,&apu_jasen,st); if ( memcmp(jasen,&apu_jasen,J_KOKO) ) { memcpy(jasen,&apu_jasen,apu_jasen.rakenne->koko); } return paluu; } /****************************************************************************/ int /* 0 = kentt„ OK */ kysy_haku( /* 1 = halutaan poistua */ Kerho_tyyppi *kerho ,/* s Kerho, jonka hakutietoja kysyt„„n. */ Haku_tyyppi *haku ,/* s,t T„ytett„v„ hakutietue */ int nro /* s Kysytt„v„ kentt„ */ ) /* ** Funktiolla kysyt„„n kent„n tiedot. Oletusarvoina k„ytet„„n ** kent„n alkuper„isi„ tietoja. ** Mik„li kentt„„n vastataan q, lopetetaan kysymykset ja ** palautetaan 1. ** ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_kentta ----------------------------------------------------------------------------*/ { Tarkistus_tyyppi tark; Jasen_tyyppi jasen; jasen.rakenne = kerho->rakenne; tark.jasen = &jasen; tark.syotto_tyyppi = SYOTTO; kopioi_jono(N_S(tark.aihe),"Hakuehto"); return kysy_kentta(nro,N_S(haku[nro]),t_ok,&tark); } /****************************************************************************/ int /* 0 = hommat OK */ kysy_hakutiedot( /* 1 = halutaan pois kysymyksest„ */ Kerho_tyyppi *kerho ,/* s Kerho, jonka hakutietoja kysyt„„n. */ Haku_tyyppi *haku /* s,t T„ytett„v„ hakutaulukko */ ) /* ** Funktiolla kysell„„n hakutaulukon tiedot. Oletusarvoina taulukon ** alkuper„iset tiedot. ** Mik„li johonkin kentt„„n vastataan q, lopetetaan kysymykset ja ** palautetaan 1. ** ** Sy”tt”: p„„tteelt„ ** Tulostus: n„ytt””n ** Kutsuu: kysy_haku ----------------------------------------------------------------------------*/ { int k,kn; char *kk = kerho->rakenne->kas_kentat[SYOTTO]; int kl; if ( tarkista_kas_kentat(kerho->rakenne,SYOTTO) ) return 1; kl = strlen(kk); printf("== tarkoittaa, ett„ kent„n TŽYTYY olla tyhj„\n"); for (k = 0; k < kl; k++) { kn = paikka(kerho->rakenne->kenttavalinnat,kk[k]); if ( kn < 0 ) continue; switch ( kysy_haku(kerho,haku,kn) ) { case 1: return 1; case -1: return 0; } } return 0; } /****************************************************************************/ int /* */ poista_jasen( /* 0 = onnistui, 1 = ep„onnistui */ Kerho_tyyppi *kerho ,/* s,t Kerho josta poistetaan. */ int poistettava /* s Poistettavan j„senen numero */ ) /* ** Funktiolla poistetaan j„sen listasta. Poisto varmistetaan k„ytt„j„lt„. ** Listaan laitetaan j„senen paikalle NULL ja itse j„sen h„vitet„„n. ** Poistettu siirret„„n toiseen tiedostoon. ** ** Sy”tt”: P„„tteelt„ ** Tulostus: N„yt”lle ** Kutsuu: odota_nappain ** talleta_poistettu ----------------------------------------------------------------------------*/ { char vastaus; char *virhe; printf("Haluatko todellakin poistaa tietueen \"%s\" (k/E):", kentta_jonoksi(0,kerho->jasenet[poistettava])); vastaus=odota_nappain("KE",'E',VAIN_ISOT); printf("\n"); if ( vastaus=='E' ) return 1; virhe = talleta_poistettu(kerho->jasenet[poistettava]); if ( !virhe ) printf("Poistettava siirretty tiedostoon %s\n",POIS_NIMI); else printf("Virhe poistettavan siirrossa:\n%s\n",virhe); free(kerho->jasenet[poistettava]); kerho->jasenet[poistettava]=NULL; printf("Tietue poistettu!\n"); kerho->muutettu = 1; return 0; } /****************************************************************************/ int /* -1 = ep„onnistui */ sijoita_kentta( /* muut = kent„n numero johon sijoitettiin */ Jasen_tyyppi *jasen ,/* t J„sen johon sijoitetaan */ Jasen_tyyppi *mista ,/* s J„sen, josta sijoitetaan */ int kentta /* s Kentt„, josta sijoitetaan */ ) /* ** Funktiolla sijoitetaan mista j„senen kentt„ jasenen siihen kentt„„n, ** jolla on sama nimi kun sijoitettavalla kent„ll„. ** ** Kutsuu: kentan_indeksi ** kentta_jonoksi, jono_kentaksi, onko_tyhjenna_jono ----------------------------------------------------------------------------*/ { char *p; int k; if ( kentta >= mista->rakenne->kenttia ) return -1; if ( kentta < jasen->rakenne->kenttia && strcmp(jasen->rakenne->kentat[kentta].nimi, mista->rakenne->kentat[kentta].nimi) == 0 ) k = kentta; else k = kentan_indeksi(jasen,mista->rakenne->kentat[kentta].nimi); if ( k < 0 ) return -1; p = kentta_jonoksi(kentta,mista); if ( p[0] == 0 ) return k; /* Tyhj„„ kentt„„ ei sijoiteta! */ if ( onko_tyhjenna_jono(p) ) p[0] = 0; jono_kentaksi(k,jasen,p); return k; }