/****************************************************************************/ /* ** T U L K K I T A . C ** ** Tiedosto sis„lt„„ TULKKI-ohjelman sanaston lukemisessa tarvittavat ** aliohjelmat. ** ** Aliohjelmassa lue_sanasto on laiteriippuva kohta: ** Turbo-C:ss„ sanaston nimeen liitet„„n se polku, josta ohjelma on ** k„ynnistynyt, joten sanaston ei tarvitse olla oletushakemistossa. ** Muissa j„rjestelmiss„ t„ytyy toistaiseksi pit„„ sanasto ** oletushakemistossa ** ** Tietorakenteet ks. TULKKI.C ** ** Aliohjelmat: ** lue_sanasto - luetaan sanasto levylt„ ja luodaan ** samalla tietorakenne ** Apualiohjelmat: ** etsi_iso_kirjain - etsii sanasta isoa kirjainta lyhennett„ varten ** tee_sanat - muuttaa merkkijonon sanaston riviksi ** lisaa_sanat - lis„„ merkkijonon sanastoon riviksi ** tee_kielet - muuttaa merkkijonon kielien nimiksi ** ** ** ** ** Tekij„t: Vesa Lappalainen ** Ohjelmointikurssi 1991 ** Tehty: 6.12.1991 ** Muutettu: ** Mit„ muutettu: ** */ #include #include #include #include "tulkki.h" #include "mjonot.h" /* ** Makro uuden sanarivin luomista varten. Tarvittava koko on ** muuten Sanat_tyypiss„, mutta taulukkoon t„ytyy saada tilaa ** lis„alkioille, eli (kielia-KIELIA_VALMIINA) uutta alkiota */ #define S_KOKO \ (sizeof(Sanat_tyyppi) + ((sanasto->kielia - KIELIA_VALMIINA)*sizeof(char *))) static char *EI_TILAA_SANOILLE = "Sanoille ei saada varattua tilaa!"; static char *VAARA_MAARA_SANOJA = "Rivill„ v„„r„ m„„r„ sanoja!"; /****************************************************************************/ char /* NULL = onnistui */ *tee_sanat( /* muuten virheilmoitus */ Sanasto_tyyppi *sanasto,/* s Sanasto, jonne sanoja ollaan tekem„ss„ */ Sanat_tyyppi *sanat ,/* s,t Sanat jonne jonon sanat laitetaan. */ char *jono /* s Jono josta sanat otetaan. */ ) /* ** Funktiolla tehd„„n jonoa vastaava merkkijono ja sanat-taulukon osoittimet ** laitetaan osoittamaan merkkijonossa oleviin eri sanoihin. ** Dynaamisesti tehd„„n koko rivi„ vastaava merkkijono. Voitaisiin ** tietysti tehd„ my”s kukin sana omana dynaamisena muuttujana, mutta ** usein pienet dynaamiset muuttujat viev„t suhteelliseti paljon tilaa. ** ** Muuttuu: jonon sis„lt” muuttuu! ** Kutsuu: laske_merkit ** tee_jono ** palanen ** poista_tyhjat ** Algoritmi: ** seuraava sanat[] ** 0 1 2 ** ----------------------------- ** sanat--->|o| o | o | o | ** -+----+------+--------+------ ** | | | | ** v ---- --- | ** | | | ** v v v ** sana_jono-------->Suomi Ruotsi Englanti ** ----------------------------------------------------------------------------*/ { char *sana_jono,*jono_os; int i,jaljella; poista_tyhjat(jono); sana_jono = tee_jono(jono); if (!sana_jono) return EI_TILAA_SANOILLE; jono_os = sana_jono; if ( laske_merkit(jono,"|")+1 < sanasto->kielia ) return VAARA_MAARA_SANOJA; for (i=0; ikielia; i++) { sanat->sanat[i] = poista_tyhjat(palanen(jono_os,"|",&jaljella)); jono_os = NULL; } return NULL; } static char *EI_SAA_TILAA = "Sanastolle ei saada varattua riitt„v„sti tilaa!"; static char *LIIAN_VAHAN_KIELIA = "Tiedostossa t„ytyy olla ainakin 2 kielt„!"; static char *LIIKAA_KIELIA = "Sanastossa liian monta kielt„!"; /****************************************************************************/ char /* NULL = onnistui */ *tee_kielet( /* muuten virheilmoitus */ Sanasto_tyyppi *sanasto,/* s,t Sanasto johon kielet liitet„„n. */ char *jono /* s Jono josta kielet etsit„„n. */ ) /* ** Funktiolla alustetaan sanastoon kielet. Mik„li jokin menee pieleen, ** palautetaan virheilmoitus. ** ** ** Muuttuu: jono ** Kutsuu: tee_sanat ** etsi_iso_kirjain ** Esimerkki: jono = "Suomi | Ruotsi | Englanti" -> ** Sanasto: ** ---------- ** |Kieli„ 3| 0 1 2 ** | |-------- ** |Lyhenteet |S|R|E| ** | |-------- ** | | 0 1 2 ** | | ----------------------------- ** |kielet o+->|o| o | o | o | ** | | ^-+----+------+--------+------ ** | | | | | | | ** | | | v | --- | ** | | | NULL | | | ** |loppu o| | | v v ** --------+- | |->Suomi Ruotsi Englanti ** | | ** |--- ----------------------------------------------------------------------------*/ { int kielia; char *virhe; kielia = laske_merkit(jono,"|")+1; if ( kielia < 2 ) return LIIAN_VAHAN_KIELIA; if ( kielia > MAX_KIELIA ) return LIIKAA_KIELIA; sanasto->kielia = kielia; if ( !(sanasto->kielet = malloc(S_KOKO)) ) return EI_SAA_TILAA; sanasto->loppu = sanasto->kielet; sanasto->kielet->seuraava = NULL; if ( (virhe=tee_sanat(sanasto,sanasto->kielet,jono)) != NULL ) return virhe; /* T„ydenn„ t„h„n lyhenteiden selvitt„minen */ return NULL; } static char *EI_AUKEA = "Tiedosto "SANASTO" ei aukea lukemista varten!"; static char *MUOTOVIRHE = "Sanastotiedostossa muotovirhe!"; /****************************************************************************/ char /* NULL = onnistui */ *lue_sanasto( /* muuten virheilmoituksen osoite */ Sanasto_tyyppi *sanasto /* t Luettu sanasto */ ) /* ** Funktiolla luetaan sanasto tiedostosta. Mik„li kaikki menee hyvin, ** palautetaan NULL. Huonossa tapauksessa tulostetaan virherivi ja ** palautetaan virheilmoitus! ** ** Kutsuu: liita_jono ** kopio_jono ** f_lue_jono ** tee_kielet ** lisaa_sanat ----------------------------------------------------------------------------*/ { FILE *f; char jono[200]=";", *virhe=NULL; f = fopen(SANASTO,"rt"); if (!f) return EI_AUKEA; do { /* Luetaan kunnes tulee 1. oikea rivi, josta lasketaan kielet */ if ( f_lue_jono(f,N_S(jono)) < OLETUS ) { virhe = MUOTOVIRHE; goto sulje; } } while (jono[0]==';'); if ( (virhe = tee_kielet(sanasto,jono)) != NULL ) goto sulje; /* T„ydenn„ t„h„n sanojen lukeminen */ sulje: if (virhe) printf("%s\n",jono); fclose(f); return virhe; }