8. diel - Textové reťazce v jazyku C
V predchádzajúcom cvičení, Riešené úlohy k 7. lekcii Céčka, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Riešené úlohy k 7. lekcii Céčka , sme si predstavili poľa. Až doteraz sme sa v našom kurze programovacieho jazyka C úspešne vyhýbali textovým reťazcom a pracovali sme iba s číslami a znakmi. V úplnej väčšine reálnych aplikácií však figurujú víceznakové texty. Tým sa v programovaní hovorí textové reťazce (keďže ide o reťaz znakov) alebo niekedy len reťazca. Dôvodom odloženia tejto témy je, že jazyk C ako nízky jazyk žiadny dátový typ pre reťazce nemá a vlastne s nimi takmer nepočíta. S textom však v céčku môžeme bežne pracovať, len je to komplikovanejšie.
Pole znakov
S reťazci možno v céčku pracovať niekoľkými spôsobmi. My si v tomto
dieli uvedieme zatiaľ ten najjednoduchší, tzv. Statický reťazec, ktorým je
pole char
ov. Keď budeme chcieť uložiť do premennej textový
reťazec "itnetwork"
, potrebujeme v pamäti vytvoriť nasledujúce
polia typu char
(znak):
'I' | 'T' | 'N' | 'E' | 'T' | 'W' | 'O' | 'R' | 'K' | '\ 0' |
\0
, čo je tzv.
Nulový znak. Tým musí končiť všetky textové reťazce.
Hoci totiž céčko ako jazyk textové reťazce nepodporuje, obsahuje
štandardné knižnice, ktoré s nimi pracujú. A preto musíme reťazca
ukladať tak, ako sa predpokladá, že budú vyzerať. Pole s reťazcom teda
musí byť vždy o 1
dlhšia, ako je dĺžka textu, ktorý
do neho vkladáme!.
Pozn .: Hoci je to nad rámec tejto lekcie, uveďme si, že nulový znak je na konci reťazca z toho dôvodu, aby sme poznali, kde reťazec končí. Okrem statických polí môžeme totiž reťazca ukladať pomocou ukazovateľov ako ľubovoľne dlhé úseky v pamäti, kde sa bez tejto barličky nezaobídeme. Tento spôsob si ukážeme ďalej v seriáli. Druhým spôsobom, ako označiť koniec reťazca, je uložiť jeho dĺžku pred prvý znak. Tento systém sa používal napr. V jazyku Pascal, oveľa častejšie sa však používa ukončenie nulovým znakom.
Vytvorme si jednoduchý príklad. Do premennej si uložme nejaký text a ten následne Vypíšme do konzoly:
{C_CONSOLE}
char text[5] = {'d', 'u', 'h', 'a', '\0'};
printf("%s", text);
{/C_CONSOLE}
výsledok:
Konzolová aplikácia
duha
Dobrá správa je, že jazyk C nám umožňuje zadávanie textu v
úvodzovkách, ktorý následne nahradí tzv. Reťazca konštantou (poľom
char
ov, zakončeným znakom \0
). Kód vyššie
môžeme prepísať na túto podobu:
{C_CONSOLE}
char text[5] = "duha";
printf("%s", text);
{/C_CONSOLE}
Všimnite si, že pole musí mať stále dĺžku 5
, aj keď má
dúha 4
písmená. Keď bude ešte dlhší, nebude to vadiť.
Dokonca na céčku môžeme nechať zistenia dĺžky textu:
{C_CONSOLE}
char text[] = "dúha";
printf("%s", text);
{/C_CONSOLE}
Čo už bohužiaľ nefunguje je priradenie reťazcové konštanty do už existujúceho poľa:
char text[5]; text = "dúha"; // Tento riadok spôsobí chybu printf("%s", text);
Je to kvôli tomu, že nemožno priradiť poľa do poľa. Nič nám však nebráni priradiť jednotlivé znaky pomocou cyklu alebo použiť funkciu kopírovania reťazcov, viď. ďalej.
Práca s jednotlivými znakmi
S reťazcom môžeme zaobchádzať úplne rovnako ako s poľom, pretože poľom je Nie je teda problém vypísať napr. 1. znak alebo ho zmeniť, prípadne reťazec skrátiť:
{C_CONSOLE}
char text[] = "dúha";
text[0] = 'h';
text[3] = '\0';
printf("%s", text);
{/C_CONSOLE}
výsledok:
Konzolová aplikácia
huh
Zmenou štvrtého znaku na \0
sme docielili ukončenie reťazca
pred týmto znakom. Na nulový znak si dajte pri editácii znakov reťazca
pozor, keď na neho zabudnete, program nebude vedieť kde reťazec končí a
dostanete sa do pamäte, ktorá vám nepatrí.
Čítanie / výpis reťazca
Reťazce môžeme jednoducho načítavať / vypisovať ako sme boli zvyknutí
doteraz, použijeme k tomu formátovacie sekvenciu %s
. Premennú
pre reťazec založíme ako pole char
ov a určíme si nejakú
maximálnu veľkosť, napr. 50 znakov (čo je veľkosť 51
). U
parametrov typu %s
vypúšťame pred premennou znak
&
, Keďže s poľom odovzdávame rovno jeho adresu.
Nasledujúci program si nechá zadať vaše meno a následne vás pozdravia:
{C_CONSOLE}
printf("Zadaj svoje meno: ");
char jmeno[51];
scanf("%50s", jmeno);
printf("Ahoj užívateľovi %s, vítam ťa!", jmeno);
{/C_CONSOLE}
Všimnite si, že vo formátovacom reťazci funkcie scanf()
je
uvedená aj maximálna dĺžka ktoý reťazca. Keď by sme ju nezadali a
natrafili na exotického používateľa alebo len na záškodníka, došlo by k
pretečeniu poľa a rozbitie programu.
Funkcia scanf()
text bohužiaľ preruší sa zadaním medzery.
Aby sme mohli načítať napr. Jan Novák "
Do jednej
premennej, upravíme formátovací reťazec ešte tak, aby načítal všetko
okrem konca riadku. Upravte si riadku s načítaním do tejto podoby (medzera na
začiatku je naozaj dôležitá, pretože v bufferi nenechá biele znaky):
{C_CONSOLE}
printf("Zadaj svoje meno: ");
char jmeno[51];
scanf(" %50[^\n]s", jmeno);
printf("Ahoj užívateľovi %s, vítam ťa!", jmeno);
{/C_CONSOLE}
Niekedy môžete pri načítaní textu z konzoly naraziť na používanie
funkcií gets()
alebo fgets()
. Funkciu
gets()
sa vyhnite, pretože neumožňuje obmedziť dĺžku ktoý
reťazca a fgets()
sa musí presmerovať na štandardný vstup. So
scanf()
si bohato vystačíme.
Štandardné funkcie pre prácu s reťazcami
Špecifikácia jazyka C nám poskytuje mnoho pripravených funkcií pre
prácu s reťazcami, ktoré zjednodušia naše programy. Pre prácu s nimi
musíme na začiatok súboru pridať vloženie hlavičkového súboru
string.h
:
#include <string.h>
Pozn .: Pretože sú funkcie pomenované pomocou skratiek, uvádzam vždy iz čoho názov vychádza pre lepšie zapamätanie.
Strlen () - String length
Dĺžku reťazca môžeme zistiť pomocou strlen()
. Jedná sa o
dĺžku viditeľnej časti bez znaku \0
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("%d", strlen("duha")); // vráti 4
return (EXIT_SUCCESS);
}
Strčte - STRING CONCATENATE
2 textové reťazce môžeme spojiť do jedného pomocou funkcie
strcat()
. Dajte pozor, aby bol v prvom reťazci dostatok
miesta.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char text[20] = "dúha";
strcat(text, " je na nebi"); // uloží do text "dúha je na nebi"
printf("%s", text);
return (EXIT_SUCCESS);
}
Strcpy () - String COPY
Keďže pole nemožno jednoducho celá kopírovať, je nám poskytnutá táto funkcia, ktorá naklonuje textový reťazec do inej premennej.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char text[5];
strcpy(text, "duha");
printf("%s", text);
return (EXIT_SUCCESS);
}
Strchr () - String CHAR
V texte si môžeme nechať vyhľadať nejaký znak. Céčko ho od začiatku
do konca prehľadá a ak znak nájde, vráti na neho tzv. Ukazovateľ. Aj keď
tie ešte nevieme, bude nám stačiť, že keď od tejto hodnoty odpočítame
reťazec, získame pozíciu, na ktorej sa znak nachádza. Ak text znak
neobsahuje, získame hodnotu NULL
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) {
char text[] = "Pán X znovu udrel.";
char *p = strchr(text, 'X'); // Zistíme pozíciu znaku 'X' v texte
int pozice = p - text;
if (p != NULL)
{
printf("Nájdených na pozíciu %d", pozice);
}
else
{
printf("Nenájdené");
}
return (EXIT_SUCCESS);
}
Asi vás neprekvapí, že sa pozícia indexuje od nuly.
Strstr () - String substring
Úplne rovnako, ako môžeme vyhľadať jeden znak, môžeme vyhľadať aj
reťazec v reťazci. O tom ďalej hovoríme ako o tzv. Podreťazci. Funkcia sa
používa analogicky s funkciou strchr()
.
Strcmp () - String Compare
Porovná 2 reťazca podľa abecedy a vráti záporné číslo, ak sa prvý
pred druhým, 0
ak sú rovnaké a kladné číslo ak je prvá za
druhým.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("%d", strcmp("akát", "blýskavice")); // vráti záporné číslo
return (EXIT_SUCCESS);
}
Funkcie pre prácu s reťazcami môžeme nájsť aj v ďalších variantoch.
Ak chceme, aby céčko pracovalo s reťazcom odzadu (napr. Vyhľadávalo od
konca), vyskytuje sa v názve funkcie písmeno r
(ako reverse).
Takou funkciou je napr. strrchr()
. Ďalšie varianty funkciou majú
v názve navyše písmeno n
(ako number) a prijímajú navyše
ďalší parameter. Ten udáva limit znakov, ktoré funkcie v reťazci
spracovávajú. Ak je reťazec dlhší, vráti len jeho časť, useknutou na
maximálny počet znakov. Pozor, táto časť neobsahuje znak \0
.
Príkladom takejto funkcie budiž strncat()
.
V budúcej lekcii, Textové reťazce v jazyku C druhýkrát - Práca so znakmi , budeme s textovými reťazcami v jazyku C pokračovať, ukážeme si ako pracovať s jednotlivými znakmi.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 922x (31.89 kB)