Merkkijonot Komentoriviparametrit

Samankaltaiset tiedostot
C-ohjelmointi, kevät Merkkijonot Komentoriviparametrit. Luento

Merkkijonot Komentoriviparametrit

C-ohjelmointi, syksy Merkkijonot Komentoriviparametrit. Luento C-ohjelmointi Syksy

Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Merkkijonot (strings) (Müldnerin kirjan luku 9) Luennon sisältö. Merkeistä. Merkkien luokittelufunktiot. Merkkijonot Komentoriviparametrit

Merkkijonot (strings) luku 9)

Moduli 5: Kehittyneitä piirteitä

Ohjeet. AS C-ohjelmoinnin peruskurssi Aalto-yliopiston sahkotekniikan korkeakoulu Tentti , Raimo Nikkila

Lyhyt kertaus osoittimista

1. Mitä seuraava ohjelma tulostaa? Vastaukseksi riittää yksi rivi joka esittää tulosteen. (6 p)

Luennon sisältö. Taulukot (arrays) (Müldnerin kirjan luku 10) Yksiulotteiset taulukot. Mikä taulukko on? Taulukko-osoitin. tavallinen osoitin

Luennon sisältö Tyypit int, char, float, double signed, unsigned short, long Vakiot const Rakenteet if, for, while, switch, do-while Syöttö ja tulostu

C-ohjelmointi, syksy 2006

C-ohjelmointi, syksy Yksiulotteiset taulukot Moniulotteiset taulukot Dynaamiset taulukot. Binääritiedostot. Luento

Ohjeet. Jaa vastauksesi konsepteille siten, etta:

Binäärioperaatiot Tiedostot ja I/O

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Binäärioperaatiot Tiedostot ja I/O

Rakenteiset tietotyypit Moniulotteiset taulukot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

Loppukurssin järjestelyt C:n edistyneet piirteet

7. Näytölle tulostaminen 7.1

Ohjelmoinnin perusteet Y Python

// // whiledemov1.c // #include <stdio.h> int main(void){ int luku1 = -1; int luku2 = -1;

Loppukurssin järjestelyt

C-kurssi kevät Luennon sisältö

Java-kielen perusteet

Luennon sisältö. C-kurssi kevät Tasokokeen kohta 1: Taulukon järjestäminen. Tasokokeen kohta 2. Tasokokeen kohta 2. Tasokokeen kohta 3

C-kurssi syksy ltö. Luennon sisält. Luento 2: tyypit, rakenteet, makrot Tyypit. signed, unsigned short,, long Vakiot const Rakenteet

Luennon sisält. ltö. C-kurssi syksy ääreet: int ja char. Yksinkertaiset tyypit. Kokonaisluvut. Merkit

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa

Sisältö. C-ohjelmointi Luento 5: Osoittimet. Keko (heap) Pino (stack) Muistinhallinta Java vs C. Prosessin rakenne

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Harjoitus 4 (viikko 47)

Osoittimet ja taulukot

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

Harjoitus 5 (viikko 48)

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

C-kurssi kevät t Luento 2: tyypit, rakenteet, makrot

Ohjelmoinnin perusteet Y Python

C-kieli mahdollistaa hyvin tiiviin ja samalla sekavan tavan esittää asioita, kuitenkin hyvän ohjelman tulisi olla mahdollisimman helppolukuinen ja

Java-kielen perusteet

Ohjelmoinnin perusteet Y Python

Tietueet. Tietueiden määrittely

Tiedosto on yhteenkuuluvien tietojen joukko, joka tavallisimmin sijaitsee kiintolevyllä, muistitikulla tai jollakin muulla fyysisellä tietovälineellä.

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Osoitin ja viittaus C++:ssa

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Java-kielen perusteita

C-ohjelmointi: Osoittimet

Java-kielen perusteet

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

C-ohjelmointi Luento 5: Osoittimet Tiina Niklander

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Harjoitus 6 (viikko 42)

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

C-ohjelmointi Luento 5: Osoittimet

Osoittimet ja taulukot

Harjoitus 6. Käytä String-luokasta vain charat- ja length-operaatioita.

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Harjoitustyö: virtuaalikone

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.

1.3Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

Metodien tekeminen Javalla

Ohjelmoinnin perusteet Y Python

int puts(char *buff) Kirjoittaa puskurissa buff \0 :lla päätetyn merkkijonon standarditulostukseen. Formatoitu konsoli-i/o Tiedostot

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi

Sisältö. 2. Taulukot. Yleistä. Yleistä

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

#include <stdio.h> // io-toiminnot. //#define KM_MAILISSA int main( ){

Ohjelmoinnin perusteet Y Python

Harjoitus 3 (viikko 39)

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin perusteet Y Python

Ohjausrakenteet. Valinta:

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla

Moduli 2: Osoittimet ja taulukot. Joel Huttunen

Listarakenne (ArrayList-luokka)

Johdatus ohjelmointiin / Lausekielinen ohjelmointi 1 & 2

Ohjelmointi 1 Taulukot ja merkkijonot

1.1 Pino (stack) Koodiluonnos. Graafinen esitys ...

Ohjelmoinnin perusteet Y Python

Sisältö. 22. Taulukot. Yleistä. Yleistä

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Ohjelmoinnin perusteet Y Python

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot

Harjoitus 2 (viikko 45)

Harjoitus 1 (viikko 44)

13 Operaattoreiden ylimäärittelyjä

Modulaarisessa ohjelmoinnissa jaetaan ohjelma osiin (moduuleihin), jotka ovat yksinkertaisia ja lyhyitä.

Taulukot. Jukka Harju, Jukka Juslin

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Transkriptio:

, kevät 2006 Merkkijonot Komentoriviparametrit Luento 7 14.3.2006 Kevät 2006 Liisa Marttinen 1

Merkkijonot (strings) (Müldnerin kirjan luku 9) C:ssä merkkijono ei ole ennaltamääritelty datatyyppi (kuten Javassa) Merkkijono on osoitin merkkeihin Osoitin mjono: Joukko merkkejä muistissa\0 Merkkijonojen käsittelyä varten standardikirjasto string.h Kevät 2006 Liisa Marttinen 2

Luennon sisältö Kirjastofunktiot merkkien käsittelyyn Merkkijonon määrittely ja alustaminen ja käyttö Merkkijonojen lukeminen ja kirjoittaminen formatoitu I/O merkkijonoille sscanf ja sprintf Riveittäin lukeminen ja tulostaminen fgets ja fputs; gets ja puts Kirjastofunktiot merkkijonojen käsittelyyn Komentoriviparametrit Kevät 2006 Liisa Marttinen 3

Merkeistä c on merkki ja c on merkkijono \0564, \xa6 datatyyppi int signed char, unsigned char L a long int esim. japanin tai kiinan merkkeihin Syöttö ja tulostus getchar, putchar scanf( format, &var), printf( format, exp) fgets, fputs, fscanf, fprintf Escape-merkit (samat kuin Javassa) '\n' = rivinvaihtomerkki '\t' = tabulaattori '\v' = pystysuora tabulointi '\b' = peruutusmerkki '\r' = rivinalkuunpalautusmerkki '\f' = sivunvaihtomerkki '\a' = hälytysmerkki, yleensä äänimerkki '\\' = kenoviiva '\'' = heittomerkki '\"' = lainausmerkki '\0' = merkkijonon lopetusmerkki if((c=getchar()) == EOF) if(scanf( %d%d, i,j)!=2) if((c=fgetc(tkahva)) == EOF).. while((c= getchar())!= \n ) while ((c=getchar())!=eof) while(getchar()!= \n ) ; Kevät 2006 Liisa Marttinen 4

#include<ctype.h> Kirjastofunktioita merkkien käsittelyyn Standardikirjaston ctype.h funktioita Merkkien luokitteluun islower(int c) isdigit(int c) palauttaa nollan, jos merkki ei ole kysyttyä tyyppiä, muuten nollasta eroavan arvon Merkkimuutoksiin tolower(int c) toupper(int c) jos muutos onnistuu, palauttaa muutetun arvon, muuten palauttaa EOF:n Kevät 2006 Liisa Marttinen 5

Merkkien luokittelufunktiot Alfanumeeriset int isalnum(int c) int isalpha(int c) int islower(int c) int isupper(int c) int isdigit(int c) int isxdigit(int c) int isodigit(int c) is c an alphanumeric is c an alphabetic letter is c a lower case letter is c an upper case letter is c a digit is c a hexadecimal digit is c an octal digit if (c>= a && c<= z ) Kirjastofunktioilla siirrettävämpää koodia! Muut merkit int isprint(int c) int isgraph(int c) int ispunct(int c) int isspace(int c) is c printable (not a control character) is c printable (not a space) is c printable (not space or alphanumeric) is c whitespace Kevät 2006 Liisa Marttinen 6

Merkkijonon määrittely ja muistinvaraaminen merkkijonolle Merkkijono määritellään osoittimena, joka osoittaa merkkeihin: char *s; Merkkijonolle pitää myös varata tilaa muistista. Myös \0-merkille on varattava tilaa Kirjastofunktiot osaavat käsitellä merkkijonona vain sellaista merkkien jonoa, joka päättyy \0-merkkiin! Esim. 10 merkin jonolle varattava 11 merkin kokoista muistialuetta: muistinvaraus -fraasi #define SIZE 10 if((s = malloc((size+1)*sizeof(char))) == NULL). Mitä tehdään varauksen epäonnistuessa? Kevät 2006 Liisa Marttinen 7

Merkkijonon alustaminen ja merkkijonon pituus s Vain muistialue, johon s osoittaa, mutta ei vielä merkkijono, koska \0 puuttuu! Alustettu, tyhjä merkkijono: s[0] = '\0'; \0 s Merkkijono, jonka pituus on 0! Merkkijonoon voidaan tallettaa lisää merkkejä: s H E L L O A L L \0 Nyt merkkijonon pituus on 9. Kevät 2006 Liisa Marttinen 8

Merkkijonon muistinvaraus ja i:nnen merkin osoittaminen Merkkijonon muistinvaraus aina calloc-funktiolla, koska calloc nullaa muistialueen => merkkijono on alustettu if((s = calloc(n+1, sizeof(char))) == NULL).. viittaus merkkijonon s i:nteen merkkiin s[i] :llä (0<= i < merkkijonon pituus) H E L L O A L L \0 s[0] s[1] s[2] s[3] s[4] s[5] s[6] s[7] s[8] S[3] = L ja s[6]= A Kevät 2006 Liisa Marttinen 9

Merkkijonon prefiksi (alkupää) ja suffiksi (loppupää) H E L L O A L L \0 s[0] s[1] s[2] s[3] s[4] s[5] s[6] s[7] s[8] s[9] s[10] Merkkijonon loppupäähän pääsee helposti käsiksi Esimerkiksi s+6 osoittaa merkkijonoa ALL, jonka pituus on 3 merkkiä s+8 osoittaa merkkijonoa L, jonka pituus on 1 merkki s+9 osoittaa tyhjää merkkijonoa, jonka pituus on 0 s+10 ei osoita mihinkään merkkijonoon! Alkupäähän esim. merkkijonoon HELL on taas vaikeampi päästä käsiksi, koska se ei pääty \0-merkkiin. Kevät 2006 Liisa Marttinen 10

Merkkijonovakio char *nimi Tarja Halonen Vakion sisältöä ei saa muuttaa On voitu tallettaa esim. read only alueelle Ei saa välittää parametrina sellaiselle funktiolle, joka muuttaa parametrinaan saamaa merkkijonoa Huomaa ero: T ja T T on merkki T nimi Tarja Halonen\0 T on merkkijono eli merkki T ja sitä seuraava null-merkki T\0 Kevät 2006 Liisa Marttinen 11

Merkkijono parametrina ja paluuarvona Koska merkkijono on itseasiassa osoitin, sitä voidaan käyttää samalla tavoin kuin osoittimia yleensä Merkkijonon tulee olla alustettu (muuten ei ole merkkijono!) Merkkijonovakioita ei saa muuttaa # funktio muuttaa # merkkijonon 1. merkin # isoksi kirjaimeksi void modify(char *s) { s[0] = toupper(s[0]); } char *p; /* EI VIELÄ! modify(p); */ if((p = calloc(10, sizeof(char))) == NULL) errorf(); p[0] = 'h'; p[1] = 'i'; /* p[2] == '\0' */ modify(p); h i \0 H i \0 H I \0 modify(p+1); char *q = "hello"; /*merkkijonovakio*/ modify(q); /* EI, EI; EEII näin! */ Kevät 2006 Liisa Marttinen 12

Merkkijono parametrina ja paluuarvona (2) (vanha merkkijono ei muutu, nyt muutos tehdään sen kopioon) char *modify(const char *s) { char *news; /* uusi merkkijono */ char *ps; /* selaa vanhaa */ char *pn; /* selaa uutta */ if ((news = calloc (length(s)+1), sizeof(char))) == NULL) return NULL; for (ps = s, pn = news; *ps; ps++, pn++) *pn = *ps; *pn = *ps; /* kopioi vielä \0-merkin /* news[0] = toupper(news[0]); return news; } Muista vapauttaa muistilohko, kun sitä ei enää tarvita: free (news); p tarja H.\0 char *p = tarja H. ; char *q = modify(p); tai char *q =modify( tarja H. ); Tarja H.\0 q = modify(p+3); p tarja H.\0 q Ja H.\0 q Kevät 2006 Liisa Marttinen 13

Erilaisia kopiointitapoja while((q[i]= p[i])!= \0 ) i++; while((*q=*p)!= \0 ) {q++; p++;} while ((*q++=*p++)!= \0 ); while (*q++ = *p++); Tekevät saman asian: kopioivat merkit merkkijonosta p merkkijonoon q. Muista varata muistista tilaa merkkijonolle q ennen kopioimista. Älä hukkaa merkkijonojen alkuja!?? Kopioitava merkkijono\0 p q Kopioita Kevät 2006 Liisa Marttinen 14

Muutetun merkkijonon palautus parametrina void modify1(const char *s, char **news) { /* return through parameter a copy of s modified*/ char *ps; /* selaa vanhaa */ char *pn; /* selaa uutta */ if (s == NULL) return -1; if ((*news = calloc (length(s)+1), sizeof(char))) == NULL) return NULL; for (ps = s, pn = *news; *ps; ps++, pn++) *pn = *ps; *pn = *ps; /* kopioi vielä \0-merkin /* (*news)[0] = toupper((*news)[0]); } char *p; modify1("hello", &p); s osoitin p: hello\0 news osoitin char osoitin, joka osoittaa osoittimeen, joka osoittaa char tyyppiseen muuttujaan news = &p Kevät 2006 Liisa Marttinen 15 ps Calloc-funktion varaama muistialue pn H e l l

Esimerkki: funktio tarkistaa, onko annettu merkkijono kelvollinen kokonaisluku joko desimaalina tai heksadesimaalina esitettynä. int isnumber(const char *s) { if (s == NULL s[0] == \0 ) /* tyhjä merkkijono */ return 0; # onko heksaluku eli tyyppiä 0x2A68? if (s[0] == 0 ) { /*nolla ensimmäisenä*/ if (s[1] == \0 ) return 1; /*pelkkä nolla kelpaa*/ if(s[1] == x s[1] == X ) /*heksaluku?*/ if (s[2] == \0 ) return 0; /* 0x ei riitä*/ for (s +=2; *s; s++) if (!isxdigit (*s)) return 0; return 1; /* kelvollinen heksaluku */ # onko desimaaliluku for (;*s; s++) if (!isdigit (*s)) return 0; return 1; Fraasi merkkijonon läpikäyntiin: for (p = s; *p; p++) käytä *p:tä; Kevät 2006 Liisa Marttinen 16

Merkkijono ja formatoitu I/O %s sekä syötössä että tulostuksessa Syötössä merkkijonon alussa olevat tyhjät ohitetaan ja lukeminen aloitetaan ensimmäisestä ei-tyhjästä merkistä Luetaan yksi sana eli seuraavaan tyhjään merkkiin asti => scanf lukee vain yhden sanan const int SIZE = 7; char *s; if ((s = malloc((size + 1) * sizeof(char))) == NULL) virhetilanne(); scanf( %s, s); scanf ( %7s,s); Entä scanf ( %SIZEs,s);? Mitä luetaan, jos syöte on Java language? Entä, jos syöte on language Java? Ei käy, sillä lainausmerkkien sisällä ei käsitellä makroja! Kevät 2006 Liisa Marttinen 17

Merkkijonon lukeminen scanf ( %s, s) koska s on osoitin Ennen lukemista merkkijonolle on oltava muistia varattuna Muistia on oltava tarpeeksi! Varmista rajoittamalla pituus. if (scanf( %10s, s)!=1) error Lukee yhden korkeintaan 10 merkin mittaisen sanan. Varaa tilaa myös \0- merkille. Kevät 2006 Liisa Marttinen 18

Merkkijonon tulostus printf( %s, str) tulostaa osoittimen str osoittaman muistilohkon kaikki merkit \0-merkkiin saakka char *s = C ja Java ovat kieliä. printf ( %s\n, s); printf ( %s\n, s+5); C ja Java ovat kieliä.\0 s s+5 Tulostus: C ja Java ovat kieliä. Java ovat kieliä. Kevät 2006 Liisa Marttinen 19

Esimerkki int lower(char *s) { /* return number of l.c. letters */ int i; char *q; for(i = 0, q = s, *q, q++) if(islower(*q)) i++; return i; } int main() { const int M = 10; char *p; if((p = calloc(m + 1, sizeof(char)) == NULL) return EXIT_FAILURE; if(scanf("%10s", p)!= 1) return EXIT_FAILURE; printf("%d lower case letters in %s\n", lower(p), p); return EXIT_SUCCESS; } Ohjelma lukee yhden korkeintaan 10 merkin mittaisen sanan ja tulostaa siinä olleiden pienten kirjainten lukumäärän. #include <stdio.h> #include <stdlib.h> #include <ctype.h> for(i = 0, q = s, *q, q++) if(islower(*q)) i++; p = s; i=0; while (*p++) if (islower(*p)) i++; Kevät 2006 Liisa Marttinen 20

sscanf ja sprintf merkkijonosta lukeminen ja merkkijonoon kirjoittaminen int sscanf (s, format, arguments) merkkijonot luvuiksi if (sscanf (p,"%lf", &sd)!=1) if(sscanf(s+6, "%d%f", &i, &d)!= 2)... 5678.993456 Luvut 34 46.998\0 Tehokkaampiakin tapoja näihin toimintoihin on! int sprintf (s, format, arguments) merkkijonon kokoamiseen osista sprintf(p, Syötetty luku oli %d, j); sprintf(s, "%s %d %f", "test", 1, 1.5); test 1 1.5\0 p:n ja s:n oltava alustettuja merkkijonoja, joille on varattu riittävästi tilaa muistista calloc-funktiolla. Kevät 2006 Liisa Marttinen 21

fgets ja fputs tiedosto merkkijono (myös stdin ja stdout) Rivi kerrallaan lukeminen ja kirjoittaminen char* fgets(char *buf, int n, FILE *in); Lukee yhden rivin, mutta enintään n-1 merkkiä tiedostosta in ja tallettaa sen muistilohkoon buf. Tallettaa myös rivinlopetusmerkit. Vaikka fgets onnistuessaan aina kirjoittaa muistilohkoon viimeiseksi \0- merkin, niin merkkijonon kelvollisuus kannattaa varmistaa: buf[strlen(buf)] = \0 ; int fputs (const char *s, FILE *out); Kirjoittaa merkkijonon s (ilman \0-merkkiä) tiedostoon out. Kevät 2006 Liisa Marttinen 22

gets ja puts stdin-syöttö ja stdout-tulostus char * gets(char *buf); Lukee aina koko rivin (ei siis korkeintaan tiettyä määrää) eikä talleta rivin lopetusmerkkiä muistilohkoon. int puts(const char *buf); Kirjoittaa merkkijonon ja päättää sen aina rivinvaihdolla. Rivi kerrallaan lukemisen yleinen ongelma: aina oletettava jokin maksimipituus jolle varataan tilaa! Kevät 2006 Liisa Marttinen 23

Merkkijono-operaatiot: <string.h> Runsaasti merkkijonoja käsitteleviä funktioita Merkkijonon pituus size_t strlen (const char *string); Huom! merkkijonojen pituuksien vertailu if (strlen(x) >= strlen(y)) if ((int)strlen(x) SIZE >= 0) Merkkijonon kopiointi char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n); Merkkijonon liittäminen toiseen char *strcat(char *dest, const char *src); char *strncat(char *dest, const char *src, size_t n) Varmista, että kopio on alustettu merkkijono kopiolle on varattu tarpeeksi muistitilaa kopioon tulee \0- merkki. Kevät 2006 Liisa Marttinen 24

Lisää merkkijono-operaatioita Merkkijonojen vertailu (merkki merkiltä) int strcmp(const char *s1, const char *s2); int strcnmp(const char *s1, const char *s2, size_t n); Merkin tai merkkijonon etsiminen char *strchr(const char *str, int c); char *strchr(const char *str, int c); <string.h> ensimmäinen c:n esiintymä viimeinen c:n esiintymä char *strstr(const char *str, const char *substr); etsii merkkijonoa Palauttaa <0 jos s1 < s2 0 jos s1 == s2 >0 jos s1 > s2 size_t strspn(const char *str, const char *set); size_t strcspn(const char *str, const char *set); 1. joukkoon kuuluva merkki 1. joukkoon kuulumaton merkki char *strpbrk(const char *str, const char *set); 1. joukkoon kuuluva merkki merkkijoukon merkkien esiintyminen merkkijonossa, palauttaa esiintymispaikan (ohitettujen merkkien lukumääränä tai osoittimena) Kevät 2006 Liisa Marttinen 25

Yhä merkkijono-operaatiota <string.h> Merkkijonon jako sanoiksi (token) erotusmerkein char *strtok(char *str, const char *sep); ensimmäisellä kerralla annettava merkkijono; seuraavilla kerroilla voi antaa sen tilalla NULL:in Tällöin jatkaa seuraavan sanan etsimistä samasta merkkijonosta. Muuttaa merkkijonoa: \0 jokaisen havaitun sanan perään. Merkkijono numeroiksi <stdlib.h> double strtod(const char *s, char **p); long strtol(const char *s, char **p, int base); unsigned long strtoul(const char *s, char **p, int base); /home/avirta/kurssi/c/2006/testi.c\0 ANSI C versioita, jotka korvaavat vanhat: atof, atoi ja atol Kevät 2006 Liisa Marttinen 26 str char *sep \ ; strtok(null, sep); Tee kopio ja käytä sitä! p s fail: s:n alkuun success: eka muuttamaton merkki

Esimerkki: Merkkijonon riisuminen turhista edesssä ja perässä olevista tyhjämerkeistä tai muista turhista merkeistä Heippa vaan \0 Heippa vaan\0 Müldnerin kirjan esimerkki 9-13 /* strip from s leading and trailing characters from * set. For example: * char *p = strip(",hi, how are you,", ","); */ char *strip(const char *s, const char *set) { int start = strspn(s, set); /* leading character*/ int end; /* trailing characters */ char *kopy; int length = strlen(s); /*merkkijonon pituus*/ if(length!= start) { /* there are characters not in s */ for(end = length; end > 1; end--) /* trailing */ if(strchr(set, s[end]) == NULL) /* onko poistettava merkki */ break; length = end - start + 1; /* left after strip */ Kevät 2006 Liisa Marttinen 27

Esimerkki jatkuu: /*char *strip() continued */ if((kopy = calloc(length + 1, sizeof(char)))==null) return NULL; memcpy(kopy, s + start, length); kopy[length] = '\0'; } /* length!= start */ else { /* here, no characters in s */ if((kopy = calloc(length + 1, sizeof(char)))==null) return NULL; strcpy(kopy, s); } return kopy; } Kevät 2006 Liisa Marttinen 28

Komentoriviparametrit int main (int argc, char **argv); int main (int argc, char *argv[]); argc merkkijonojen lukumäärä argv osoitin osoitinlohkoon ohjelmannimi parametri1 parametri 2 echo Hello, world argv argv[0] argv[1] echo\0 Hello,\0 argc = 3 argv[2] world\0 -merkit echo Hello, world argv echo\0 toimivat argv[0] joissakin järjestelmissä! argv[1] Hello, world\0 argc = 2 Kevät 2006 Liisa Marttinen 29

Osoittaminen komentoriviargumentteihin etsi Virtanen Ville rektiedosto argc: 4 argv: argv[0] argv[1] etsi\0 Virtanen\0 argv[2] Ville\0 argv[3] rektiedosto\0 argv[0] tai argv osoittaa 1. parametriin eli ohjelman nimeen ( etsi ), argv[1] tai argv+1 osoittaa 2. parametriin ( Virtanen ) argv[2] tai argv+2 osoittaa 3. parametriin ( Ville ) argv[3] tai argv+3 osoittaa 4. parametriin ( rektiedosto ) argv[0][0] tai (*argv)[0] tai **argv osoittaa 1. parametrin 1. merkkiin argv[2][4] tai (*(argv+2))[4)] tai *(*(argv+2)+4) osoittaa 3. parametrin 5. merkkiin.

Komentoparametrien lukumäärän tarkistus /* Tarkista komentoriviparametrien lukumäärä! */ int main(int argc, char **argv) {. switch(argc) { case 4: /* kaikki tiedot annettu komentorivillä*/ case 3: /*OK! käytetään oletusarvoa*/ default: fprintf(stderr, Väärä käyttötapa: %s.. \n", argv[0]); /*Voisi myös kertoa oikean käytötavan!*/ return EXIT_FAILURE; } Kevät 2006 Liisa Marttinen 31

Komentoriviparametrien käyttö: Tiedoston rivien tulostus näytölle #define DEFAULT 10 #define MAX 80 /*tulostaa näytölle tiedoston n ensimmäistä riviä */ int display(const char *fname, int n, int Max); int main(int argc, char **argv) { int lines = DEFAULT; switch(argc) { case 3: /* selvitä rivien lukumäärä argumentti */ if(argv[1][0]!= '-' sscanf(argv[1] + 1, "%d", &lines)!=1 lines <= 0) return EXIT_FAILURE; argv++; /* no break: retrieve filename */ case 2: if(display(argv[1], lines, MAX) == 0) return EXIT_FAILURE; break; default: return EXIT_FAILURE; } return EXIT_SUCCESS; } argv argv[0] argv[1] argv[2] ohjelman nimi show\0 rivien lkm show -n fname - = argumentti on optionaalinen; voi puuttua tiedoston nimi testi\0 Kevät 2006 Liisa Marttinen 32 -n\0 argv argv[0] argv[1] show\0 testi\0

Ohjelma laskee ja tulostaa parameteina annettujen lukujen summa #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int i; double luku, summa=0.0; char **p; char *s; if (argc==1) { printf ("Parametreja voi olla vaihteleva"); printf (" määrä ja ne voivat olla"); printf (" kokonaislukuja tai liukulukuja"); printf ("\nkäyttö: SUMMA arg1 arg2... argn\n"); exit(0); /* lopetetaan ohjelman toiminta */ } if ((s = calloc(80, sizeof(char))) == NULL) return 1; p = &s; for (i=1; i<argc; i++) { luku = strtod(argv[i], p); summa=summa+luku; } printf ("Lukujen summa on %.2lf\n",summa); return 0; } Kevät 2006 Liisa Marttinen 33

Mitä opittiin? Merkkijonojen alustaminen ja käsittely Merkkijonojen syöttö ja tulostus Standardikirjaston funktioita merkkijonojen käsittelyyn Komentoriviparametrien käyttö Kevät 2006 Liisa Marttinen 34

Ensi kerralla Taulukoiden käsittelyä Yksiulotteiset taulukot Määrittely, kopiointi, vertailu Taulukko parametrina Alustus ja talletus Moniulotteiset taulukot Dynaamiset taulukot Kevät 2006 Liisa Marttinen 35