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;
}