/****************************************************************************/ /* ** M J O N O T . C ** ** Yleisiä merkkijonojen käsittelyyn liittyviä aliohjelmia. ** ... ** Aliohjelmat: ** tee_jono - luo uuden merkkijonon jonne jono kopioidaan ** kopioi_jono - kopioi kork. annetun määrän merkkejä ... ** merkkijonossa ** wildmat - vertaa onko sana == maski, missä maskissa ** voi olla jokeri- merkkejä ... */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "mjonot.h" char *VALIMERKIT=" .,- ;:?!"; /****************************************************************************/ char /* = jonon kopion osoite */ *tee_jono( /* NULL = ei voida kopioida */ char *jono /* s Kopioitava merkkijono */ ) ... ... Kuten ennenkin ... ... /****************************************************************************/ int /* */ wildmat( /* 0 = jono täsmää maskiin */ /* 1 = jono ei täsmää maskiin */ const register char *s ,/* s Tutkittava jono */ const register char *m /* s Maski, johon jonoa verrataan */ ) /* ** Funktiolla tutkitaan täsmääkö annettu jono verrattavaan maskiin. ** Maski saa sisältää seuraavia erikoismerkkejä: ** * vastaa 0-n merkkiä ** ? vastaa mitä tahansa yhtä merkkiä ** ** Algoritmi: Kysymysmerkki ja tavallinen kirjain normaalisti ** Jos tulee vastaan tähti joka ei ole jonon lopussa, ** niin ongelmahan on oikeastaan ** (koska tähän asti kaikki on ollut oikein) ** "Onko loppujono sama kuin toisen jonon loppu JOSTAKIN ** kohdasta alkaen"? ** Siis kokeillaan sovittaa loppujonoa aliohjelman itsensä ** (rekursio) avulla kaikkiin mahdollisiin loppupaikkoihin. ** Esimerkki: s = "Kissa" m = "*ss*" -> 0 ** = "*ss" -> 1 ** Vika alkuperäisessä algoritmissa: ** Jos m="*a" ja s="" ja s[1]!=0 (mikä tietysti sallittua!) ** niin vastaus oli 0. ** Korjattu 29.1.1994/vl muuttamalla rekursion jälkeinen ** if (!*++s) return 1; ** muotoon ** if (!*s || !*++s) return 1; ----------------------------------------------------------------------------*/ { while (*m) { /* Jos kokeiltavaa jonoa on jäljellä */ if (*m == '?') { /* Jos kysymysmerkki, niin kaikki kelpaa */ if (!*s) return 1; /* paitsi jos jono on loppunut! */ } else if (*m == '*') { /* Jos * niin katsotaan onko viimeinen */ if (*++m) /* Jollei * viimeinen, niin kokeillaan */ while (wildmat(s, m)) /* loppujonoa jokaiseen eri paikkaan. */ if (!*s || !*++s) return 1;/* Jos jono loppuu kesken ei täsmää! */ return 0; /* Muuten samat (* viimeinen tai loppujono*/ } /* täsmäsi) */ else if (*s != *m) /* Jos samat merkit niin tietysti OK! */ return 1; s++; m++; /* Kummassakin jonossa eteenpäin */ } return *s; /* Jos jono loppui yhtäaikaa, niin OK! */ } ...
Olemme lisänneet kirjastoon muutamia uusia aliohjelmia, joiden tarpeellisuuden totesimme jo kerhorekisterin suunnitteluvaiheessa.
Kirjastossa on mm. wildmat- aliohjelma merkkijonojen samaistamiseksi, kun jonossa saa esiintyä jokerimerkkejä * ja ? (vrt. MS- DOS).
aluksi s = "Kissa"; *s='K' s++ - > s = "issa" *s='i' s++ - > s = "ssa" *s='s'