Reťazce alebo "ukecané polia".

Čo je to pole už vieme. Naučili sme sa, ako si vyrobiť statické pole, ktorého dĺžku pozná program od začiatku aj ako si nechať prideliť kus pamäte s pomocou funkcie malloc. Poďme sa teraz podrobnejšie pozrieť na jeden konkrétny typ polí. Ide o pole premenných typu char. Do takéhoto poľa možno uložiť veľa písmeniek. A veľa písmeniek môže utvoriť slovo alebo dokonca aj vetu. A polia, do ktorých môžeme uložiť nejaký text sa nazývajú reťazce.

Prvý problém je, ako nejaký text do poľa dostať. Jedna z možností je dať ho tam v momente, keď pole deklarujeme. Môže to vyzerat takto:

    char pole[10] = "Ahoj";
Tento príkaz vyrobí pole desiatich charov. Inicializácia však na počudovanie nezmení prvé štyri z nich, ale prvých päť. Podľa očakávania prebehne niečo ako pole[0]='A'; pole[1]='h'; pole[2]='o'; pole[3]='j'; Okrem toho sa ale na koniec zapíše špeciálny ukončovací znak '\0', takže sa ešte uskutoční niečo ako pole[4] = '\0';. Nulový znak signalizuje, kde reťazec končí. Vďaka nemu funkcie, ktoré s reťazcami pracujú vedia, že ostatné prvky poľa už do reťazca nepatria.

Ďalšia možnosť, ako dostať text do poľa je takáto:

    char pole[] = "Ahoj";
V tomto prípade sme nechali na kompilátore, aby sám určil správnu dĺžku poľa. Dĺžka bude 5 a už sa až do konca behu programu nezmení. (Prečo dĺžka poľa nebude 4?)

Zatiaľ to vyzeralo všetko jednoducho a príjemne. Teraz prídu problémy. Čo robiť, ak máme už deklarované pole a potrebujeme ho naplniť až neskôr? Ak sa pokúsime o niečo takéto:

    char pole[10];
    pole = "Ahoj";
kompilátor nám vynadá, pretože premenná pole je smerník, ktorý ukazuje na pevno na začiatok poľa a my sa ju pokúšame presvedčiť, aby ukazovala niekde inde. Máme dve možnosti. Buď tam to "Ahoj" napchať po písmenkách, alebo použiť funkciu. Prvá možnosť je únavná a zdĺhavá (zvlášť pri dlhších reťazcoch) a preto odporúčame druhú. Keď chceme používať funkcie na prácu s reťazcami, potrebujeme include-ovať ďalší súbor -- string.h. Na kopírovanie jedného reťazca do iného slúži funkcia strncpy. Použije sa nasledovným spôsobom:
    strncpy(pole,"Ahoj",9);
    pole[9] = '\0';
Funkcia má tri parametre. Prvý je smerník do pamäte, kam sa má reťazec ukladať. Druhý parameter je reťazec, ktorý sa má skopírovať. Tretí parameter je maximálny počet znakov, ktoré sa skopírujú. V uvedenom prípade, kedy poznáme dĺžku kopírovaného reťazca sa zdá byť zbytočný. Ak by sme ale kopírovali reťazec uložený v nejakom inom poli, celkom ľahko by sa mohlo prihodiť, že by bol pridlhý a do nášho poľa by sa nezmestil. A tak by sa prepísalo miesto v pamäti za poľom. Dĺžku sme obmedzili na 9 znakov aby nám ostalo ešte jedno miesto na ukončovací znak, ktorý sa v prípade pretečenia nepridáva. (Mimochodom -- jedna známa metóda na prienik do operačných systémov je založená práve na využití programátorskej chyby, že sa nekontroluje pretečenie dĺžky reťazca.)

Na výpis reťazca slúži stará dobrá funkcia printf. Riadiaci znak je ale nový. Ak chcem vypisovať reťazec, urobím to takto: printf("%s",pole); Ak chcem reťazec načítať z klávesnice, použijem funkciu fgets. Spravím to takto:
fgets(pole,9,stdin); Funkcia fgets prečíta jeden riadok zo súboru určeného tretím parametrom (ak miesto súboru napíšem stdin, bude čítať z klávesnice) a vloží ho do reťazca určeného prvým parametrom. Číslo v strede mi zas hovorí, koľko maximálne znakov sa môže prečítať.

Pre vaše potešenie je tu ešte niekoľko funkcií, ktoré pracujú s reťazcami: Funkcia strlen zistí dĺžku reťazca. Teda strlen("Ahoj") bude 4. Funkcia strcmp vie porovnať dva reťazce podľa abecedy. Ak je prvý menší výsledok je záporné číslo, ak je väčší, kladné a ak sú reťazce rovnaké, výsledok je 0. Teda
strcmp("Adam","Eva") je -4, (nie je dôležité, že práve -4, hlavné je, že je to záporné), strcmp("Eva","Adam") je 4 a strcmp("Adam","Adam") je 0. Funkcia strncat(pole,"te",4) skopíruje na koniec reťazca pole maximálne 4 znaky z druhého reťazca. Ak tam teda predtým bolo "Ahoj", bude tam teraz "Ahojte".

Funkcií pracujúcich z reťazcami je ešte viac. Ich zoznam si pod LINUXom môžete pozrieť príkazom man string a popis jednotlivých funkcií napr. príkazom man strlen. Kto pracuje pod DOSom alebo Windowsami, musí si zohnať knižku.



Úloha č.1 Deklarujte si reťazec dlhý 20, načítajte doňho niečo z klávesnice a vypíšte, akú to má dĺžku.

Úloha č.2 Načítajte dva reťazce z klávesnice a vypíšte ten, ktorý je podľa abecedy skôr.

Úloha č.3 Načítajte z klávesnice reťazec a zistite, koľkokrát sa v ňom vyskytuje písmeno 'a'.

Úloha č.4 Deklarujte si jeden reťazec dĺžky 40 a dva dĺžky 20. Do dvoch menšich reťazcov načítajte hodnoty z klávesnice, do veľkého vložte reťazec, ktorý vznikne spojením tých malých a výsledok vypíšte. (Pozor! Budete musieť použiť funkciu strncpy aj funkciu strncat.)

Anino Belan 2003-10-26