Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

13.2.2 C- kielen merkkijonot

Vaikka C++:sta löytyykin hyvä merkkijonoluokka <string>, niin joudumme silti tutustumaan myös puhtaan C- kielen merkkijonoihin. Miksikö? Koska esimerkiksi sijoituksessa

	cpp_jono = "Kissa";

sijoitetaan tosiasiassa C- merkkijono C++:n merkkijonoon. Lisäksi valtava määrä valmiista aliohjelmista haluaa parametrikseen nimenomaan C- merkkijonon tai palauttaa C- merkkijonon. Itse asiassa C++:n merkkijonojen käyttö on vielä tänä päivänä (2002) ei ole yleistä edes kaikissa C++:n omissakaan funktiokirjastoissa.

Tämä on sääli, sillä suurin osa C:n "huonoudesta" johtuu nimenomaan aloittelijoiden (ja kokeneidenkin) käsissä VAARALLISISTA merkkijonoista. Valtava määrä UNIXeistakin löytyvistä tietoturva- aukoista perustuu väärin käytettyihin merkkijonoihin! Näytimmekin jo aikaisemmin valmiiden olioluokkien kohdalla muutamia asioita, joita EI voi tehdä C- merkkijonoilla, tai jotka näyttävät hyvältä, mutta toimivat väärin. Nyt tutustumme vähän tarkemmin ongelmien syihin ja siihen miten niitä voidaan välttää.

Vinkki
A

Varaa tila myös loppumerkille

C- kielen merkkijonot eivät ole mitään muuta kuin taulukoita kirjaimista. Merkkijonoista on kuitenkin sovittu, että merkkijonon lopuksi taulukossa on merkki jonka koodi on 0 (NUL, '\0'). Siis merkkijono täytyy muistaa varata yhtä alkiota isommaksi , kuin aiottu merkkien maksimimäärä.

Huomattakoon, ettei ole olemassa valmista NUL- vakiota, vaan pitää käyttää joko muotoa 0 tai ' \0'.

string.h- kirjastosta löytyy iso kasa merkkijonojen käsittelyyn tarkoitettuja aliohjelmia. Esimerkiksi sijoitus

	elain = "Kissa"

ei onnistu (tai onnistuu, muttei kopioi merkkejä "Kissa" taulukkoon elain), vaan on käytettävä jotakin funktioita (esimerkiksi huippuvaarallista strcpy funktiota):

	char elain[12];
	strcpy(elain,"Kissa");           /* VAARALLINEN!!! Tässä toimii!!! */
	...
	
	Seuraavassa koodit on esitetty heksana ja 
	? tarkoittaa ettei muistipaikan arvoa tunneta.
	
	elain
	  |      0  1  2  3  4  5  6  7  8  9 10 11 
	  |    +-----------------------------------+ 
	  +--->|4B|69|73|73|61|00| ?| ?| ?| ?| ?| ?|
	       +-----------------------------------+
	        K  i  s  s  a  NUL ?  ?  ?  ?  ?  ? 

Merkkijonon pituus voitaisiin laskea seuraavalla aliohjelmalla:

c-taul\merkit.c - esimerkki merkkijonon viemisestä parametrina

	int pituus(const char jono[])
	{
	  int i;
	  for (i=0; jono[i]; i++);
	  return i;
	}
	
	/* Tai: */
	
	int pituus(const char jono[])  /* const char [] ei char []            */
	{                              /* koska jonoa ei muuteta              */
	  char *p;
	  for (p=jono; *p; p++);
	  return p- jono;
	}

Tosin string.h:sta löytyy funktio strlen, joka tekee täsmälleen saman asian.

Funktio pituus voitaisiin aivan yhtä hyvin esitellä:

	int pituus(const char *jono) 


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys