Audi||20
/****************************************************************************/ char /* */ *palanen( /* Osoitin merkkijonon palaseen. */ char *jono ,/* s Pätkittävä jono, turmeltuu! */ char *erottimet ,/* s Merkit joiden kohdalta katkaistaan. */ int *jaljella /* t Paljonko jonoa on vielä jäljellä (- 1 loppu)*/ ) /* ** Funktiolla pätkitään merkkijonoa osiin. 1. kutsukerralla välitetään ** tutkittava jono ja tämän jälkeen seuraavilla NULL osoitin. ** Funktio vaihtaa löytämänsä erotinmerkit null- merkeiksi! ** ** Muuttuu: jono ** Algoritmi: ** Esimerkki: 012345678901234 ** jono="Aku|Ankka||12" erottimet="|" ** 1. kutsu palanen(jono,"|",&j) - > "Aku" , j=10 ** 2. kutsu palanen(NULL,"|",&j) - > "Ankka", j=4 ** 3. kutsu palanen(NULL,"|",&j) - > "" , j=3 ** 4. kutsu palanen(NULL,"|",&j) - > "12" , j=0 ** 5. kutsu palanen(NULL,"|",&j) - > "" , j=- 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { static char *st=""; static int p1=0,p2=0,pit=0; if (jono) { /* 1. kutsukerta, alustetaan apumuuttujat */ st = jono; pit = strlen(jono); p1 = 0; } else p1 = p2+1; /* Muilla kerroilla jatketaan siitä mihin viim. jäätiin. */ if ( p1 > pit ) { *jaljella = - 1; return st+pit; /* Tyhjä merkkijono, kun osoitetaan jonon null- tavuun. */ } p2 = p1+strcspn(st+p1,erottimet); st[p2] = 0; *jaljella = pit- p2; return st+p1; }
Funktio strcspn palauttaa ensimmäisen indeksin, josta löytyy erottimet merkkijonon jokin merkki. Mikäli merkkiä ei löydy, palautetaan jonon pituus.
Funktion toimintaidea on seuraava:
2. Kutsu: p = palanen(NULL,"|",&j); Kutsuun tultaessa: (pit == 19, p1 == 0, p2 == 7)
+---st +---st+p2+1 v v 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 +-------------------------------------------------+ | |V|o|l|v|o| | | | |1|2|3|0|0| ||| |1| | | | | | | +--------------0-----------------------0----------+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
Etsitään |- merkkiä alkaen paikasta 8. Löytyy jonoon st+p2+1 nähden paikasta 8. Siis alkuperäiseen jonoon nähden paikasta 16. Muutetaan arvot: (pit == 19, p1 == 8, p2 = 8+8)
+---st +---st+p1 +----st+p2 v v v 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 +-------------------------------------------------+ | |V|o|l|v|o| | | | |1|2|3|0|0| | | |1| | | | | | | +--------------0-----------------0-----0----------+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
palautetaan st+p1 ja *jaljella = 19- 16 = 3Näin olemme saaneet funktion, jota voidaan huoletta kutsua myös merkkijonon loppumisen jälkeenkin:
int rivi_tuotteeksi(char *rivi, Tuote_tyyppi *tuote) { char *p; int j; p = palanen(rivi,"|",&j); poista_tyhjat(p); kopioi_jono(N_S(tuote- >nimike),p); p = palanen(NULL,"|",&j); if ( sscanf(p,"%lf",&tuote- >hinta) != 1 ) return 1; p = palanen(NULL,"|",&j); if ( sscanf(p,"%d",&tuote- >kpl) != 1 ) return 1; return 0; }