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



Samankaltaiset tiedostot
Tietueet. Tietueiden määrittely

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

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

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

Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

Lyhyt kertaus osoittimista

Alkupiiri (5 min) Lämmittely (10 min) Liikkuvuus/Venyttely (5-10min) Kts. Kuntotekijät, liikkuvuus

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

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

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

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

Rakenteiset tietotyypit Moniulotteiset taulukot

Työvoima Palvelussuhdelajeittain %-jakautumat

Ohjausrakenteet. Valinta:

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

Ohjelmoinnin perusteet Y Python

Osoittimet ja taulukot

Osoitin ja viittaus C++:ssa

Osoittimet ja taulukot

Ohjelmoinnin perusteet Y Python

Moduli 5: Kehittyneitä piirteitä

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Ohjelmoinnin perusteet Y Python

if-lauseen yksinkertaisin muoto on sellainen, missä tietyt lauseet joko suoritetaan tai jätetään suorittamatta.

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot

Moduli 2: Osoittimet ja taulukot. Joel Huttunen

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

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

Java-kielen perusteita

Loppukurssin järjestelyt C:n edistyneet piirteet

Ohjelmassa on käytettävä funktiota laskeparkkimaksu laskemaan kunkin asiakkaan maksu. Funktio floor pyöristää luvun lähimmäksi kokonaisluvuksi.

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

Ohjelmoinnin perusteet Y Python

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

Loppukurssin järjestelyt

5.6. C-kielen perusteet, osa 6/8, Taulukko , pva, kuvat jma

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla:

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

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

Ohjelmointi 1 Taulukot ja merkkijonot

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

13 Operaattoreiden ylimäärittelyjä

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

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

Ohjelmoinnin perusteet Y Python

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

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

Ohjelmoinnin perusteet Y Python

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

Ohjelmoinnin perusteet Y Python

TIETORAKENTEET JA ALGORITMIT

Java-kielen perusteet

Taulukoiden käsittely Javalla

Ohjelmoinnin perusteet Y Python

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-kieli mahdollistaa hyvin tiiviin ja samalla sekavan tavan esittää asioita, kuitenkin hyvän ohjelman tulisi olla mahdollisimman helppolukuinen ja

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

Tietorakenteet ja algoritmit

Johdatus ohjelmointiin / Lausekielinen ohjelmointi 1 & 2

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Java-kielen perusteet

3.1 Mitä tarkoittaan heredoc? Milloin sitä kannattaa käyttää? Kirjoita esimerkki sen käyttämisestä.

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

Ohjelmoinnin peruskurssi Y1

Harjoitus 4 (viikko 47)

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

Ohjelmoinnin perusteet Y Python

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

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

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 kevät Luennon sisältö

Ohjelmoinnin perusteet Y Python

ITKP102 Ohjelmointi 1 (6 op)

Java-kielen perusteet

Harjoitus 2 (viikko 45)

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

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

Ohjelmoinnin perusteet Y Python

Ohjelmointiharjoituksia Arduino-ympäristössä

Plagioinnin tunnistaminen lähdekielisistä ohjelmista

Ohjelmoinnin perusteet Y Python

C-ohjelmointi, syksy 2006

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

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

ITKP102 Ohjelmointi 1 (6 op)

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

Zeon PDF Driver Trial

Binäärioperaatiot Tiedostot ja I/O

17. Javan omat luokat 17.1

Merkkijonot ja C++ Antti-Juhani Kaijanaho. 5. maaliskuuta Vanhojen C++-kääntäjien käyttäjät, huomio! 2 Merkkijonojen perusteet

Transkriptio:

Merkkijonot C-kielessä merkkijono on taulukko, jonka alkiot ovat char -tyyppiä. Taulukon viimeiseksi merkiksi tulee merkki '\0', joka ilmaisee merkkijonon loppumisen. Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille: char mjono [9]; /* tallettaa max. 8 kpl merkkejä! */ 341

Merkkijono voidaan alustaa merkkijonovakiolla, jolloin kääntäjä laskee taulukon koon ja tallettaa merkkijonon merkit taulukkoon: char mjono [] ="Eka arvo"; 0 1 2 3 4 5 6 7 8 E k a a r v o \0 Merkkijonon lopetusmerkiksi lisätään automaattisesti '\0' eli NUL-merkki, jonka avulla tunnistetaan jonon loppu. Lopetusmerkillekin on varattava tilaa! 342

Omissa funktioissa koodaajan tulee huolehtia NUL-merkin lisäämisen merkkijonon loppuun. Jos alustus tehdään seuraavasti: char mjono [8] ="Eka arvo"; 0 1 2 3 4 5 6 7 E k a a r v o Tässä tilanteessa NUL-merkki talletetaan taulukon ulkopuolelle, mahdollisesti jonkin toisen muuttujan sisällöksi. 343

n:n kokoisessa merkkijonotaulukossa voidaan esittää merkkijonoja, joiden pituus vaihtelee välillä 0... i -1, koska tilaa on varattava myös lopetusmerkille. NUL-merkin jälkeisillä alkioiden arvoilla ei ole merkitystä, merkkien ei tarvitse täyttää koko taulukkoa. char merkkijono[10] = "ABCDEF"; 0 1 2 3 4 5 6 7 8 9 'A' 'B' 'C' 'D' 'E' 'F' '\0' 344

Merkkivakiot ja merkkijonovakiot eroavat toisistaan siten, että merkkivakiot kirjoitetaan heittomerkkien väliin ja merkkijonovakiot kirjoitetaan lainausmerkkien väliin. Merkkijonojen ja yksittäisen merkin esitys tietokoneen muistissa on erilainen. 1. char merkki = "a"; 2. char merkkijono[10] = {'a'}; Esimerkkirivillä 1 yritetään tallettaa kahta merkkiä char - tyyppiseen muuttujaan, sillä merkkijono "a" koostuu kahdesta merkistä 'a' ja '\0'. Esimerkkirivillä 2 taulukko merkkijono[10] ei esitä merkkijonoa, koska taulukossa ei ole merkkijono lopetusmerkkiä '\0'! 345

Merkkijonotaulukko toteutetaan kaksiulotteisella char -taulukolla. char merkkijonoja [10][31]; Taulukon ensimmäinen indeksi 10 kertoo montako merkkijonoa taulukkoon voi tallettaa ja toinen indeksi 31 ilmaisee, että rivin merkkijonon pituus voi olla enintään 30 merkkiä, jotta lopetusmerkki mahtuu mukaan. 346

Merkkijonotaulukko voidaan määritellä ja alustaa seuraavasti. char kuukaudet[12][10] = {"Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"}; 347

Taulukko näyttäisi tällaiselta: T a m m i k u u \0 H e l m i k u u \0 M a a l i s k u u \0 H h t i k u u \0 T o u k o k u u \0 K e s ä k u u \0 H e i n ä k u u \0 E l o k u u \0 S y y s k u u \0 L o k a k u u \0 M a r r a s k u u \0 J o u l u k u u \0 348

Merkkijonojen käsittely Merkkijonojen käsittelyyn printf - ja scanf -funktioiden avulla on oma kentänmäärittely %s. printf -funktiolla tulostettaessa voidaan määrittää myös tulostuskentän leveys, kirjoittamalla numero % ja s merkkien väliin %10s. Jos tulostettava merkkijono on lyhyempi kuin kentän leveys tasataan tulostus tulostuskentän oikeaan reunaan. Jos halutaan tasata tulostuskentän vasempaan reunaan käytetään kentän leveyden määrityksen edessä - merkkiä %-10s. 349

Jos tulostettava teksti on pitempi kuin kentänleveysmäärityksessä on määritelty, kentänleveysmääritys menettää merkityksensä. #include <stdio.h> int main(void){ char nimi1[21] = "Kalle"; char nimi2[21] = "Uuno Välkky"; /* tulostetaan merkkijono "nimi1" selitysteksteineen nimen sisältö tasattuna tulostuskentän oikeaan reunaan */ printf("nimi1 sisältää \"%15s\" nimen\n", nimi1); 350

} /* tulostetaan merkkijono "nimi1" selitysteksteineen nimen sisältö tasattuna tulostuskentän vasempaan reunaan */ printf("nimi1 sisältää \"%-15s\" nimen\n", nimi1); /* tulostetaan merkkijono "nimi2" siten että tulostuskentän leveys on liian lyhyt */ printf("nimi2 sisältää \"%5s\" nimen\n", nimi2); printf("\n\n"); return 0; 351

Funktiolla scanf voidaan lukea koko merkkijono, jolloin parametrina välitetään merkkijonomuuttujan ensimmäisen alkion osoite joka on sama kuin merkkijonomuuttujan nimi. 352

#include <stdio.h> int main(void){ } char nimi1[21]; printf("syötä merkkijono >"); scanf("%s", nimi1); /* huomaa ei &-merkkiä nimi1:n edessä */ printf("\nsyötit merkkijonon \"%s\"\n\n", nimi1); return 0; scanf lukee merkkijonon taulukkoon nimi1 ja lisää automaattisesti lopetusmerkin merkkijonon perään. 353

Funktiolla scanf ei voi lukea merkkijonoja, jotka sisältävät välilyöntejä. Funktio scanf lukee merkkijonomuuttujaan vain välilyöntimerkkiin asti olevat merkit ja jättää loput merkit näppäimistöpuskuriin. Tämä saattaa joskus aiheuttaa ohjelmassa kummallista käytöstä. 354

#include <stdio.h> int main(void){ } char nimi1[21]; char nimi2[21]; printf("syötä 1. merkkijono >"); scanf("%s", nimi1); printf("\n\nsyötä 2. merkkijono >"); scanf("%s", nimi2); printf("\n\nsyötit 1. merkkijonoksi \"%s\"\n\n", nimi1); printf("\nsyötit 2. merkkijonoksi \"%s\"\n\n", nimi2); return 0; 355

356

Funktion scanf sijasta voidaan käyttää funktiota fgets, joka löytyy kirjastosta string.h. Funktiolle täytyy antaa kolme parametria: 1.Merkkijonomuuttujan nimi, jonne fgets tallettaa lukemansa merkkijonon 2.Merkkijonomuuttujan maksimikoko 3.Tiedosto, josta luetaan. Jos luetaan näppäimistöltä, nimeksi laitetaan stdin. 357

fgets lukee merkkejä kunnes luetaan enter tai on luettu merkkijonon koko -1 merkkiä. Jos merkkijonomuuttujan koko on suurempi kuin luetun merkkijonon koko talletetaan enterin painallus myös merkkijonomuuttujan sisällöksi ja vasta sen jälkeen tulee merkkijonon loppumerkki. Jos syötetty merkkijono on saman mittainen kuin merkkijonomuuttujan koko-1, merkkijonoon ei talleteta enteriä, vaan se jää näppäimistöpuskuriin stdin. Tämä saattaa jälleen aiheuttaa ohjemassa outoa toimintaa. Esimerkkiohjelma fgets - funktion käytöstä, jossa on huomioitu edellä mainitut tilanteet. 358

#include <stdio.h> #include <string.h> #define JONOPIT 80 void luepois(void); /* näppäimistöpuskuin tyhjentäjä */ int main ( void ) { char nimi[jonopit]; char pois; /* luetaan enintään 79 merkkiä (JONOPIT-1) */ printf("anna nimesi >"); fgets( nimi, JONOPIT, stdin ); 359

/* jos syötetty merkkijono oli lyhyempi kuin mitä nimimuuttujaan mahtuu, on '\n' eli enter/return */ if( nimi[strlen(nimi)-1] == \n ) nimi[strlen(nimi)-1] = \0 ; /* loppumerkki oikeaan paikkaan */ else luepois(); /* tyhjentää lukupuskurin */ printf(" OK, nimesi on %s\n", nimi); } return ( 0 ); void luepois(void){ while( getc(stdin)!= '\n'); } 360

Merkkijonoja voidaan tulostaa myös funktiolla puts char nimi[] = "Matti"; puts(nimi); /* tulostaa merkkijonon nimi sisällön */ 361

Ohjelmissa täytyy ottaa aina huomioon se, että luettava merkkijono mahtuu sille varattuun tilaan. Jos luettava merkkijono on pitempi kuin sille varattu tila, tallettuvat loput merkit mahdollisesti jonkin toisen muuttujan muistialueelle (puskuriylivuoto). Merkkijonojen käsittelyssä usein tarvittava apufunktio on strlen, joka palauttaa merkkijonoon kuuluvien merkkien määrän, kuitenkaan jonon loppumerkkiä '\0' ei lasketa pituuteen mukaan! 362

#include <stdio.h> #include <string.h> int main ( void ) { char nimi[] = "Matti"; int pituus; } pituus = strlen(nimi); printf("merkkijonon \"%s\" pituus on %d\n\n", nimi, pituus); return 0; 363

364

Merkkijonojen käsittelyfunktioita Merkkijonojen käsittelyfunktioita löytyy kirjastosta string.h Merkkijonojen kopiointi Merkkijonoja ei voi kopioida sijoitusoperaattoria = käyttämällä. Sijoitusta voidaan käyttää vain alustuksessa merkkijonon määrittelyn yhteydessä, ohjelman muissa osissa merkkijonojen sijoitukset on tehtävä erillisen kopiointifunktion strcpy avulla. strcpy ( kopio, kopioitava ); 365

jossa kopio ja kopioitava ovat kahden ennalta määritellyn merkkijonomuuttujan nimet Funktio kopioi jonon kopioitava sisällön jonon kopio sisällöksi NUL-merkki ('\0') mukaanlukien olettaen, että jonossa kopio on riittävästi tilaa. Funktiolla strncpy kopioidaan myös merkkijono toiseen merkkijonoon, se saa kolmanneksi parametriksi kopioitavien merkkien lukumäärän. strncpy ( kopio, kopioitava, lukumäärä ); HUOMIO: Funktio ei lisää merkkijonon lopetusmerkkiä! 366

char mjono1[10]; char mjono2[] = "abcdefg"; /*Kopioidaan 3 ensimmäistä merkkiä mjono2:sta mjono1:een */ strncpy ( mjono1, mjono2, 3 ); mjono[3] = '\0'; /* lisätään NUL-merkki */ Tilanteen huomioimatta jättäminen aiheuttaa ohjelmassa outoa käyttäytymistä, jonka selvittäminen voi olla aloittelijalle työlästä. 367

Merkkijonon loppuun voidaan lisätä toinen merkkijono funktiolla strcat. #include <stdio.h> #include <string.h> int main ( void ) { char nimi[25] = "C-ohjelmointi"; char k[] = " -kurssi"; printf("\nnimi-muuttuja: %s\n", nimi); strcat( nimi, k ); printf("\nnimi-muuttuja lisäämisen jälkeen: %s\n\n", nimi); } return 0; 368

369

Merkkijonojen vertailu tehdään funktiolla strcmp. strcmp (mjono1, mjono2); Funktio tarkistaa edeltääkö mjono1 mjono2:ta aakkosjärjestyksessä. Vertailua tehdään merkki merkiltä kunnes ero löytyy tai merkkijonot loppuvat. Jos eroa ei löydy palauttaa funktio arvon 0 eli merkkijonot ovat samanlaiset. Jos mjono1 edeltää mjono2:ta, palauttaa funktio negatiivisen kokonaisluvun (mjono1 < mjono2). Jos mjono2 edeltää mjono1:tä funktio palauttaa positiivisen kokonaisluvun (mjono1 > mjono2). 370

Funktio strcmp vertaa oikein vain merkkijonoja, jotka eivät sisällä skandeja (å, Å, ä, Ä, ö, Ö). Esimerkkiohjelma ilmoittaa saamiensa nimien aakkosjärjestyksen: #include <stdio.h> #include <string.h> void luepois( void ); int main ( void ) { char nimi1[ 21 ]; char nimi2[ 21 ]; printf("anna nimi ( nimi saa olla max 20 merkkiä): "); fgets ( nimi1, 21, stdin ); 371

if( nimi1[strlen(nimi1)-1] == \n ) nimi1[strlen(nimi1)-1] = \0 ; else luepois(); /* tyhjentää lukupuskurin */ printf("anna nimi ( nimi saa olla max 20 merkkiä): "); fgets ( nimi2, 21, stdin ); if( nimi[strlen(nimi2)-1] == \n ) nimi2[strlen(nimi2)-1] = \0 ; else luepois(); /* tyhjentää lukupuskurin */ 372

if( strcmp ( nimi1, nimi2) == 0 ) { printf("nimet ovat samat"); }else{ if(strcmp ( nimi1, nimi2) < 0 ) { printf("%s on aakkosissa aikaisemmin kuin %s\n", nimi1, nimi2); }else{ printf("%s on aakkosissa aikaisemmin kuin %s\n", nimi2, nimi1); } } } /* main */ void luepois( void ){ while( getc(stdin)!= '\n' ); } 373

Merkkijonon voi pilkkoa osamerkkijonoksi jonkin erotinmerkin tai erotinmerkkijonon avulla käyttämällä funktiota strtok. char * strtok(merkkijono, erotinmerkkijono); Esimerkiksi päiväyksenn lukeminen muodossa "9.9.2010". 374

#include <stdio.h> #include <string.h> void luepois( void ); int main ( void ) { char paivays[13]; char * osamerkkijono; char erotinmerkkijno[] = "."; char selitystekstit[3][11] ={"Paiva: ","Kuukausi: ", "Vuosi: "}; int i; /* valitsee selitystekstin */ printf("anna paivays muodossa \"paiva.kuukausi.vuosi\" > "); fgets ( paivays, 13, stdin ); 375

if( paivays[strlen(paivays)-1] == '\n') paivays[strlen(paivays)-1] = '\0'; else luepois(); /* tyhjentää lukupuskurin */ osamerkkijono = strtok( paivays, erotinmerkkijno); i = 0; while( NULL!= osamerkkijono ){ printf("%10s %s\n", selitystekstit[i], osamerkkijono); /* strtok "muistaa" merkkijonon, NULL kertoo että jatka entisen merkkijono käsittelyä */ osamerkkijono = strtok( NULL, erotinmerkkijno); i = i+1; } } /* main */ 376

void luepois( void ){ while( getc(stdin)!= '\n' ); } 377