/****************************************************************************/ /* ** K E R H O E T S . C ** ** Kerhosta tietyn ehdon tyttvien jsenien etsiminen ** ** Aliohjelmat: ** lajittele - tekee permutaatiotaulukon valitun kentn ** mukaisesti ** etsi_indeksit - etsii annetun maskin ehdon tyttvi jseni ** kysy_kentat_ja_etsi - interaktiivinen kysyminen, etsiminen, ** selaaminen, korjailu ja poisto ** laske_montako_muuta - etsii onko muita kuin valittua jsent ** ** ** Tekijt: Vesa Lappalainen ** Ohjelmointikurssi 1991 ** Tehty: 13.11.1991 ** Muutettu: 17.11.1991/vl ** Mit muutettu: rakennetta siistitty ** listty lajittelu ** Muutettu: 23.11.1991/vl ** Mit muutettu: tyyppiksite yleistetty ** Muutettu: 24.12.1991/vl ** Mit muutettu: epyhtlhaku ** negatiivisten lukujen lajittelu korjattu ** tyhjn sotun lajittelu korjattu ** Muutettu: 4.12.1993/vl ** Mit muutettu: laita_selaus_kohdalla korjattu siten, ettei ** viimeisen poisto nyt vr jsent */ #include #include #include #include "mjonot.h" #include "kerho.h" #define MERKKEJA 256 /****************************************************************************/ /* ** T i e t o t y y p i t */ typedef struct { /* Lajittelussa apuna kytettv tietue. */ int kentan_nro; /* Kentt jonka mukaan lajitellaan. */ Jasen_tyyppi **jasenet; /* Osoitin osoitintaulukon alkuun. */ } Vertaa_tyyppi; /* */ typedef struct { /* Avaimen muodostuksessa kytett tyyppi */ int alustettu; /* Onko taulukko alustettu vai ei. */ char avainarvo[MERKKEJA]; /* Miten kukin kirjain muuttuu */ } Jarjestys_avain_tyyppi; /* /****************************************************************************/ /* ** G l o b a a l i t muuttujat */ static Jarjestys_avain_tyyppi JARJESTYS = {0,""}; /* Avaimen muodostuksessa kytettv taul. */ /****************************************************************************/ /* ** A L I O H J E L M A T */ #define A_1(mika,miksi) j->avainarvo[(unsigned char)mika] = miksi #define A_A(mi,mp,miksi) A_1(mi,miksi); A_1(mp,miksi) /****************************************************************************/ void /* */ alusta_jarjestys( /* */ Jarjestys_avain_tyyppi *j /* s,t Alustettava jrjestystaulukko. */ ) /* ** Aliohjelmalla alustetaan avaimen muodostamisessa tarvittava taulukko. ** Tyhj, vlimerkit ja tuntemattomat = 0x20 ** '0' = 0x30 ... '9' = 0x39 ** 'A' = 0x41 ... 'Z' = 0x5a ** '' = 0x5b ... ** ** ----------------------------------------------------------------------------*/ { int i; if (j->alustettu) return; j->alustettu = 1; for (i=0; iavain); if (i<20) { printf("TEE AVAIN: Liian pieni avainkentt!\n"); return; } tyyppi = kentan_tyyppi(kentan_nro,jasen); p = kentan_osoite(kentan_nro,jasen); switch (tyyppi) { case Tjono: kopioi_jono(N_S(jasen->avain),p); poista_tyhjat(jasen->avain); for (a=(unsigned char *)jasen->avain; *a; a++) { *a = JARJESTYS.avainarvo[*a]; } poista_tyhjat(jasen->avain); return; case Tsotu: kopioi_jono(N_S(s),p); liita_jono(N_S(s)," "); kopioi_jono(N_S(jasen->avain),s); jasen->avain[0] = s[4]; /* Vaihdetaan pv ja vuosi keskenn! */ jasen->avain[1] = s[5]; jasen->avain[4] = s[0]; jasen->avain[5] = s[1]; return; case Tint: i = *(int *)p; sprintf(jasen->avain,"%+05d",i); if ( jasen->avain[0] == '-' ) jasen->avain[0]='+'-1; /* jotta - < + */ return; case Tdouble: d = *(double *)p; sprintf(jasen->avain,"%+015.7lf",d); if ( jasen->avain[0] == '-' ) jasen->avain[0]='+'-1; /* jotta - < + */ return; default: printf("TEE AVAIN: Ei ole kentt %d!\n",kentan_nro); return; } } static Vertaa_tyyppi VERTAA; /* Tiedonvlitys lajittele -> vertaile */ /****************************************************************************/ int /* -1 1. pienempi */ vertaile( /* 0 Yhtsuuria */ /* 1 1. suurempi */ const void *a ,/* s 1. verrattavan indeksi. */ const void *b /* s 2. verrattavan indeksi. */ ) /* ** Funktiolla verrataan kahta indeksin avulla annettua jsent toisiinsa. ** Verrattava kentt katsotaan globaalista muuttujasta VERTAA.kentan_nro. ** ** Globaalit: VERTAA ----------------------------------------------------------------------------*/ { return (strcmp( VERTAA.jasenet[*(int *)a]->avain, VERTAA.jasenet[*(int *)b]->avain )); } /****************************************************************************/ void /* */ lajittele( /* */ /* */ Kerho_tyyppi *kerho ,/* s Lajiteltava kerho */ Jarjestys_tyyppi *jarj ,/* s,t Lajiteltava permutaatiotaulukko */ int kentan_nro /* s Mink kentn mukaan lajitellaan */ ) /* ** Funktiolla lajitellaan jarj taulukko annetun kentn mukaan oikeaan ** jrjestykseen. Lajiteltava kentt valitaan kentan_nro mukaan. ** Mikli jarj.indekseja = 0, alustetaan taulukko 0 1 2 3 ** muuten kytetn olemassa olevaa numerointia. ** Ei viel jrjest AND ja OR etsimisen mukaan! ** ** Globaalit: Kytt vertaa -funktion kanssa yhteist aluetta VERTAA ** Kutsuu: qsort ** Algoritmi: Vlitetn permutaatiotaulukko qsort aliohjelmalle ----------------------------------------------------------------------------*/ { int j,ind,max_ind; if ( (kentan_nro < 0) || !jarj->jarjesta ) return; /* Permutaation alustus tarvittaessa. */ if ( jarj->indekseja == 0 ) { max_ind = jarj->max_koko; if ( max_ind > kerho->jasenia ) max_ind = kerho->jasenia; ind = 0; for (j=0; jjasenet[j] ) /* NULL-jseni ei laiteta */ jarj->indeksit[ind++] = j; jarj->indekseja = ind; } for (j=0; jindekseja; j++) { tee_avain(kentan_nro,kerho->jasenet[jarj->indeksit[j]]); } VERTAA.kentan_nro = kentan_nro; VERTAA.jasenet = kerho->jasenet; qsort( (void *)(jarj->indeksit), /* Lajiteltava taulukko */ jarj->indekseja, /* Taulukon alkioiden lukumr */ sizeof(jarj->indeksit[0]), /* Yksittisen alkion koko */ vertaile); /* Vertailualiohjelman nimi */ } /****************************************************************************/ int /* 0 = ei lydy muita joihin tsm */ laske_montako_muuta( /* muuten muiden tsmvien mr */ Kerho_tyyppi *kerho ,/* s Kerho josta etsitn */ int kentta ,/* s Kentt johon verrataan */ char *jono ,/* s Jono jota etsitn */ int kuka_ei ,/* s Henkil jota ei etsit. */ int *viimeinen ,/* t Indeksi viimeiseen lytyneeseen */ int *oliko_kuka_ei /* t Oliko se joka ei saa olla */ ) /* ** Funktiolla lasketaan montako muuta ehdon tsmlleen tyttv jsent ** kerhosta lytyy. Palautetaan parametrina mys viimeinen johon tsmsi. ** ** Algoritmi: Verrataan jokaista paitsi ei-etsittv. ----------------------------------------------------------------------------*/ { int j,montako=0; *viimeinen = -1; *oliko_kuka_ei = 0; for (j=0; jjasenia; j++) { if ( strcmp(jono,kentta_jonoksi(kentta,kerho->jasenet[j]) ) == 0 ) { if ( j == kuka_ei ) *oliko_kuka_ei = 1; else { montako++; *viimeinen = j; } } } return montako; } /****************************************************************************/ typedef enum { YHT, ERIS, PIEN, PIENYHT, SUUR, SUURYHT } Vertailu_oper_tyyppi; typedef struct { char *ehto; int pit; Vertailu_oper_tyyppi kasky; } Vertailu_tyyppi; static Vertailu_tyyppi EHDOT[] = { { "" , 0, YHT}, { "==", 2, YHT}, { "!=", 2, ERIS}, { "<=", 2, PIENYHT}, { "<" , 1, PIEN}, { ">=", 2, SUURYHT}, { ">" , 1, SUUR}, { NULL, 0, YHT} }; /****************************************************************************/ int /* 1 = ei tsm */ tutki_tasmaako( /* 0 = tsm */ Jasen_tyyppi *jasen ,/* s Tutkittva jsen */ char *ikentta ,/* s Kentt muutettuna isoiksi kirjaimeksi */ char *maski ,/* s Maski muutettuna isoiksi kirjaimeksi */ int knro /* s Kentn numero. */ ) /* ** Funktiolla tutkitaan onko annettu ehto voimassa. Ehdot: ** <, <= ,> , >= , !=, == ** Mikli ehtoa ei ole annettu, tulkitaan ehto tavalliseksi ** wildmat vertailuksi. ** ** Globaalit: EHDOT ** Muuttuu: jasen->avain ** Kutsuu: kentta_jonoksi ** jono_kentaksi ** wildmat ** Esimerkki: ikentta "20", maski "<=50" -> 0 ----------------------------------------------------------------------------*/ { int i,tulos,ehto_ind=0; char *m; Jasen_tyyppi mjasen; for (i=1; EHDOT[i].ehto; i++) if ( strstr(maski,EHDOT[i].ehto) == maski ) { ehto_ind = i; break; } m = maski+EHDOT[ehto_ind].pit; switch ( EHDOT[ehto_ind].kasky ) { case YHT: return wildmat(ikentta,m); case ERIS: return !wildmat(ikentta,m); case PIEN: case PIENYHT: case SUUR: case SUURYHT: jono_kentaksi(knro,&mjasen,m); tee_avain(knro,&mjasen); tee_avain(knro,jasen); tulos = strcmp(jasen->avain,mjasen.avain); switch ( EHDOT[ehto_ind].kasky ) { case PIEN: return !(tulos<0); case PIENYHT: return !(tulos<=0); case SUUR: return !(tulos>0); case SUURYHT: return !(tulos>=0); } default: return 1; } } /****************************************************************************/ int /* */ etsi_indeksit( /* = lytyneiden indeksien lukumr */ Kerho_tyyppi *kerho ,/* s Kerho josta etsitn */ int kentta ,/* s Kentn numero, josta etsitn (tai AND,OR) */ Haku_tyyppi *maski ,/* s Arvot joiden mukaan etsitn. */ Jarjestys_tyyppi *etsi /* t Taulukko jonne lytyneet talletetaan */ ) /* ** Funktiolla etsitn maskin mukaisia kentti rekisterist. ** Palautetaan taulukossa niiden paikkojen indeksit, joista ** maski lytyi. Mikli kentt on OR etsitn TAI-toimintona kaikkia ** kentti (eli jos yksikin kentt tsm) ja mikli kentta==AND ** etsitn JA-toimintona (eli kaikkien kenttien tytyy tsmt). ** Jos maskin kentt on tyhj, ei kentt verrata lainkaan. ** Jos maskin kentt alkaa ~, niin vastaavan kentn tytyy olla tyhj. ** Mikli ketn ei lydy, laitetaan silti indeksit[0]=0, jotta siihen voidaan ** varmasti viitata. ** ** Kutsuu: jono_isoksi ** kopioi_jono, N_S ** wildmat ** Algoritmi: Kokeillaan jokaista paikkaa ja merkitn lytymt yls. ** Isot ja pienet kirjaimet samaistetaan. ----------------------------------------------------------------------------*/ { char isana[80],*m; int j,k,k1=kentta,k2=kentta,samat,yksi_riittaa=1; if ( kentta==ETSI_AND || kentta==ETSI_OR ) { k1=0; k2=KENTTIA-1; } etsi->indekseja=0; etsi->indeksit[0]=0; if ( kentta == ETSI_AND ) yksi_riittaa=0; /* Muille paitsi ANDille */ for (k=k1; k<=k2; k++) jono_isoksi(maski[k]); for (j=0; jjasenia; j++) { /* Tutkitaan kaikki jsenet */ if (!kerho->jasenet[j]) continue; /* Ohitetaan NULL-osoittimet*/ samat=0; for (k=k1; k<=k2; k++) { /* Tarkistetaan kentt. */ kopioi_jono(N_S(isana),kentta_jonoksi(k,kerho->jasenet[j])); jono_isoksi(isana); m = maski[k]; if (!*m) continue; /* Tyhjist kentist ei vlitet. */ samat = !tutki_tasmaako(kerho->jasenet[j],isana,m,k); if ( samat && yksi_riittaa ) break; /* Yksi ja TAI lytyi */ if ( (!samat) && (!yksi_riittaa) ) break; /* JA ei lydy */ } if ( samat ) { etsi->indeksit[etsi->indekseja++]=j; if ( etsi->indekseja>=etsi->max_koko ) break; } } if ( etsi->indekseja > 1 ) lajittele(kerho,etsi,k1); return etsi->indekseja; } /****************************************************************************/ void /* */ laita_selaus_kohdalla( /* */ Kerho_tyyppi *kerho ,/* s Selailtavan kerho tiedot. */ Selaus_tyyppi *selaus /* s,t Selattavat tiedot. */ ) /* ** Aliohjelmalla laitetaan selaus-tietueen kohdalla kentn arvo oikeisiin ** rajoihin. Samalla muutetaan kerhon nykyjsen. ** Muuttuu: selaus->kohdalla ** kerho->nykyjasen ----------------------------------------------------------------------------*/ { if ( selaus->kohdalla < 0 ) selaus->kohdalla = 0; if ( selaus->kohdalla >= selaus->selattavat->indekseja ) selaus->kohdalla = selaus->selattavat->indekseja - 1; /* korj. 4.12.93 */ if ( selaus->selattavat->indekseja <= 0 ) { /* Tm vain kun mitn ei ole*/ selaus->selattavat->indekseja = 0; selaus->kohdalla = 0; selaus->selattavat->indeksit[0] = 0; } kerho->nykyjasen = selaus->selattavat->indeksit[selaus->kohdalla]; } /****************************************************************************/ char /* */ selaile( /* Viimeksi painettu merkki (paitsi + tai -) */ Kerho_tyyppi *kerho ,/* s Selailtavan kerho tiedot. */ Selaus_tyyppi *selaus /* s,t Selattavat tiedot. */ ) /* ** Funktiolla selataan selaus-listassa olevia henkilit. ** Mikli painetaan muuta kuin + tai -, palautetaan painettu nppin. ** Painetuiksi sallitaan kuitenkin vain listassa olevat nppimet ** sek +, - ja RET. ** Aluksi tulostetaan kohdalla oleva henkil (mikli tllainen on olemassa). ** Tmn jlkeen tulostetaan viesti, johon listn mahdollisesti pern ** tieto + ja - kytst, mikli nm ovat olemassa. ** ** Muuttuu: selaus->kohdalla ** kerho->nykyjasen ** Sytt: nppimist ** Tulostus: nyttn ** Kutsuu: tulosta_jasen ** kopioi_jono, N_S ** liita_jono ** odota_nappain ** Esimerkki: viesti = "Selaile" vali = ' ' ja on selattavia kump. suuntaan ** tulostaa kohdalla olevan jsenen tiedot ja ** "Selaile, seuraava (+), edellinen (-):" ----------------------------------------------------------------------------*/ { int suunta=0; char painettu,vali; char sallitut[80]; while (1) { selaus->kohdalla += suunta; laita_selaus_kohdalla(kerho,selaus); if ( selaus->selattavat->indekseja > 0 ) {/* Jos joku on kohdalla, tulos*/ printf("\n"); printf("#%03d ------------------------------------------------------\n", kerho->nykyjasen+1); tulosta_jasen(stdout,kerho->jasenet[kerho->nykyjasen]); printf("------------------------------------------------------------\n"); } printf("%s",selaus->viesti); vali = selaus->vali; kopioi_jono(N_S(sallitut),selaus->sallitut); /* Jos voidaan selata eteenpin */ if ( selaus->kohdalla < selaus->selattavat->indekseja-1 ) { printf(",%c%c = seuraava (%d)", vali,NAP_SEURAAVA,selaus->selattavat->indekseja-selaus->kohdalla-1); liita_jono(N_S(sallitut),NAP_SEUR_LOPPU); vali = ' '; } if ( selaus->kohdalla > 0 ) { /* Jos voidaan selata taaksepin*/ printf(",%c%c = edellinen (%d)", vali,NAP_EDELLINEN,selaus->kohdalla); liita_jono(N_S(sallitut),NAP_EDEL_ALKU); } printf(":"); painettu=odota_nappain(sallitut,NAP_RET,VAIN_ISOT); suunta = 0; switch (painettu) { case NAP_EDELLINEN: suunta = -1; break; case NAP_SEURAAVA: suunta = 1; break; case NAP_ALKUUN: selaus->kohdalla=0; break; case NAP_LOPPUUN: selaus->kohdalla=selaus->selattavat->indekseja-1; break; default : return painettu; } } } /****************************************************************************/ void /* */ tayta_viesti_ja_sallitut( /* */ int korj_poisto ,/* s Onko korjaus ja poisto mukana? (0=ei, 1=on)*/ Selaus_tyyppi *selaus /* s,t Paikka jonne tiedot tytetn. */ ) /* ** Aliohjelmalla tytetn viesti muotoon: ** Valitse kent jonka mukaan etsitn (?=kenttlista uudell.) ** Mikli korjaus ja poisto on sallittu, listn viestiin viel ** ,\npoisto (P), korjailu (K) ** Samoin sallittujen kirjaimien joukkoon laitetaan kaikki kenttlistan ** mukaiset kirjaimet sek ? J T (lista, JA, TAI) ja tarvittaessa P ja/tai K. ** ** Muuttuu: selaus->viesti ** selaus->sallitut ** Kutsuu: kopioi_jono, N_S ** liita_jono ----------------------------------------------------------------------------*/ { char viestin_jatko[80]; kopioi_jono(N_S(selaus->viesti), "Valitse kentt jonka mukaan etsitn (?=kenttlista uudell.)"); selaus->vali = '\n'; /* Tytetn nppinlistaan nyt sallitut nppimet */ kopioi_jono(N_S(selaus->sallitut),KENTTAVALINNAT); if ( strlen(selaus->sallitut) > KENTTIA ) selaus->sallitut[KENTTIA]=0; /* Poistetaan listasta ylim. kirjaimet */ liita_jono(N_S(selaus->sallitut),NAP_JA_TAI); liita_jono(N_S(selaus->sallitut),"?"); /* Jos korj ja poisto sallittu ja on joku jota nytt ruudussa. */ if ( korj_poisto && selaus->selattavat->indekseja>0 ) { sprintf(viestin_jatko,",\n%c = poisto, %c = korjailu", NAP_POISTO, NAP_KORJ); liita_jono(N_S(selaus->viesti),viestin_jatko); liita_jono(N_S(selaus->sallitut),NAP_KORJ_POISTO); selaus->vali = ' '; } } /****************************************************************************/ char /* */ selaile_ja_odota_valinta( /* */ Kerho_tyyppi *kerho ,/* s Selailtava kerho */ Selaus_tyyppi *selaus ,/* s,t Tietue jonne lytymis yms. tiedot laitetaan*/ int korj_poisto /* s Onko korjailu ja poisto sallittu */ ) /* ** Funktiolla tytetn nytlle tuleva kysymys ja sallitut nppimet sek ** tmn jlkeen annetaan selaus-funktion hoitaa tehtvi kunnes painetaan ** jotain muuta kuin + tai -. Mikli painetaan ? tulostetaan kenttlista ** ja jatketaan viel selailua kun lydettyjen lista on tyhjennetty. ** ** Muuttuu: etsi.selattavat ** Sytt: nppimist ** Tulostus: nyttn ** Kutsuu: tayta_viesti_ja_sallitut ** selaile ----------------------------------------------------------------------------*/ { char painettu; /* Kyselln kunnes ei en haluta kenttlistaa. */ do { tayta_viesti_ja_sallitut(korj_poisto,selaus); painettu = selaile(kerho,selaus); printf("%c\n",painettu); if ( painettu == '?' ) { printf("\n\n"); tulosta_kenttalista(selaus->sallitut); printf("\n"); selaus->selattavat->indekseja = 0; /* Jottei lista rullaa pois kuvasta*/ } } while ( painettu == '?' ); return painettu; } /****************************************************************************/ int /* -1 = eponnistui */ varaa_jarjestys( /* 0 = onnistui */ Kerho_tyyppi *kerho ,/* s */ int koko ,/* s Taulukolle varattava koko */ Jarjestys_tyyppi *loytyi/* t */ ) /* ** Funktiolla varataan tilaa jrjestystaulukolle mikli max_koko=-1. ** Samalla muut kentt alustetaan siten, ett on yksi lytynyt joka ** osoittaa nyky_jaseneen. ** Jos koko<=0, niin varataan tilaa kerhon jsenistn verran. ** ----------------------------------------------------------------------------*/ { if ( loytyi->max_koko == -1 ) { if ( koko <= 0 ) koko = kerho->jasenia; /* Luodaan etsimistaulukko. Jsenien mr riitt tss aliohjelmassa */ /* koska jseni ei list tll. Lopetetaan mikli tilaa ei saada! */ if ( !(loytyi->indeksit = malloc(sizeof(int)*koko)) ) return -1; loytyi->max_koko = koko; loytyi->indekseja = 1; loytyi->indeksit[0] = kerho->nykyjasen; loytyi->jarjesta = 1; } return 0; } /****************************************************************************/ int /* -1 = eponnistui */ etsi_indekseja( /* Lytyneiden kenttien lukumr. */ Kerho_tyyppi *kerho ,/* s,t Kerho josta etsitn */ int kentan_nro ,/* s Kentn numero, jonka mukaan etsitn */ Jarjestys_tyyppi *loytyi/* t Taulukko jonne lytyneet talletetaan. */ ) /* ** Funktiolla etsitn kerhosta kentst kentan_nro niit jseni, joilla ** ko. kentss on kerho->haku ehdon tyttvt tiedot. Jos kentn numero ** on JA tai TAI, niin koko tietueen tiedot kytetn hyvksi. ** Mikli lytyneit on yli yksi, tulostetaan lytyneiden lukumr. ** Voidaan kutsua mys alustamattomalla taulukolla, mikli sen max_koko=-1; ** tllin taulukko alustetaan ja varataan sille tarvittava permutaatio ** taulukko. ** ** Muuttuu: kerho->nykyjasen ** Tulostus: nytn ** Kutsuu: etsi_indeksit ----------------------------------------------------------------------------*/ { if (varaa_jarjestys(kerho,0,loytyi)) return -1; etsi_indeksit(kerho,kentan_nro,kerho->haku,loytyi); if ( loytyi->indekseja > 1 ) printf("Thn tsm %d jsent:\n",loytyi->indekseja); kerho->nykyjasen = loytyi->indeksit[0]; return loytyi->indekseja; } /****************************************************************************/ int /* -1 = eponnistui */ alusta_selaustaulukko( /* 0 = onnistui, */ Kerho_tyyppi *kerho ,/* s Kerho josta etsitn. */ Selaus_tyyppi *selaus ,/* t Alustettava taulukko. */ Jarjestys_tyyppi *loytyi/* s Kytettev jrjestystaulukko. */ ) /* ** Funktiolla varataan tilaa selaustaulukolle ja alustetaan se sisltmn ** vain kerhon nykyjsen. Mikli tilaa ei saada, palautetaan -1. ** Selaustaulukko pit muistaa vapauttaa kutsulla: ** free(selaus->selattavat.indeksit); ** ** Kutsuu: malloc ----------------------------------------------------------------------------*/ { if ( !kerho->jasenia ) return -1; /* Turha etsi jollei ole jseni! */ if ( !kerho->haku ) { /* Onko hakumaskia ennestn? */ if ( !(kerho->haku = calloc(KENTTIA,sizeof(kerho->haku[0]))) ) return -1; /* 1. kerralla hakuehto laitetaan tyhjksi. calloc hoiti tmn! */ } if (varaa_jarjestys(kerho,0,loytyi)) return -1; selaus->kohdalla = 0; selaus->selattavat = loytyi; return 0; } /****************************************************************************/ int /* -1 = etsiminen ei onnistu */ kysy_kentat_ja_etsi( /* Muuten lytyneiden kenttien lukumr */ Kerho_tyyppi *kerho ,/* s,t Kerho josta etsitn. */ int korj_poisto /* s Onko korjailu ja poisto mukana (1=on, 0=ei)*/ ) /* ** Funktiolla kysytn mink kentn mukaan etsitn, kysytn ** tiedot ja etsitn ehdot tyttvien kenttien indeksit. ** Nit voidaan sitten selata yls tai alas. Mys korjailu ** ja poisto on mahdollista, jos korj_poisto=1. ** ** Sytt: Pttelt ** Tulostus: Nyttn ** Kutsuu: ks. alla ----------------------------------------------------------------------------*/ { int poistettuja=0; char painettu; /* Viimeksi painettu nppin nppimen */ int kentan_nro; /* Kun painettu nppin muutetaan kentn nroksi */ Selaus_tyyppi selaus; Jarjestys_tyyppi loytyi = {-1}; if ( alusta_selaustaulukko(kerho,&selaus,&loytyi) ) return -1; while ( (painettu = selaile_ja_odota_valinta(kerho,&selaus,korj_poisto) ) != NAP_RET ) { /* Tutkitaan painettua nppint. Jos jokin kenttlistasta, kysytn */ /* sen kentn arvo ja etsitn. */ kentan_nro = paikka(KENTTAVALINNAT,painettu); if ( kentan_nro < 0 ) continue; /* Itse asiassa nin ei voi kyd! */ if ( kentan_nro < KENTTIA ) { if ( kysy_haku(kerho->haku,kentan_nro) ) break; etsi_indekseja(kerho,kentan_nro,&loytyi); selaus.kohdalla=0; } /* Ei mikn kenttlistasta. Onko jokin muu tunnettu? */ switch (painettu) { case NAP_KORJ : printf("Korjaa tietoja tarvittaessa!\n"); kysy_jasenen_tiedot(kerho,kerho->jasenet[kerho->nykyjasen],PAIVITYS); break; case NAP_POISTO: if ( !poista_jasen(kerho,kerho->nykyjasen) ) { /* Selaustaulukko pit korjata! */ if ( --selaus.selattavat->indekseja >0 ) memmove( selaus.selattavat->indeksit + selaus.kohdalla, selaus.selattavat->indeksit + selaus.kohdalla+1, sizeof(selaus.selattavat->indeksit[selaus.kohdalla])* (selaus.selattavat->indekseja - selaus.kohdalla) ); poistettuja++; } break; case NAP_JA: printf("Tyt JA-hakuehdot:\n"); if ( kysy_hakutiedot(kerho->haku) ) break; etsi_indekseja(kerho,ETSI_AND,&loytyi); selaus.kohdalla=0; break; case NAP_TAI: printf("Tyt TAI-hakuehdot:\n"); if ( kysy_hakutiedot(kerho->haku) ) break; etsi_indekseja(kerho,ETSI_OR,&loytyi); selaus.kohdalla=0; break; } } free(selaus.selattavat->indeksit); if (poistettuja) poista_NULL(kerho); return selaus.selattavat->indekseja; }