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ä (1997) varsin harvinaista.
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
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ä esimerkiksi 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:
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)