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)