Hlavní strana -> Programování v C -> 10. Znaková pole - řetězce

10. Znaková pole - řetězce

No minule jsem toho moc nenapsal. Co byste taky chtěli psát k jednomu příkazu, žeano. V předminulém díle jsem sliboval příkaz switch a pole a řetězce a hory a doly atd. Switch máme zkrku, tak se vrhnem na ty pole a řetězce. Podrobněji jsou pole probrány v následujícím dílu, tady ještě jejich přesnou teorii nepotřebujeme

Co to tedy řetězec vlastně je? Řetězec je v podstatě posloupnost znakových konstant. Například věta je řetězcem. Zatím jsme měli jedině datový typ schopen uchovat jeden znak, tedy datový typ char. Co kdybychom chtěli mít v paměti uloženo třeba "ahoj"? Vytvářet 4 proměnné typu char a přiřazovat jim postupně písmena a, h, o a j by bylo značně nemotorné a v praxi nepoužitelné. V našem případě je "ahoj" řetězcem. Některé programovací jazyky mají pro řetězec vlastní datový typ, ale C-čko takový typ nemá a tak si musíme pomoct jinak. Uděláme to tak, že si vytvoříme pole. Pole znaků. Jak velké to pole znaků má být záleží na tom, jak moc dlouhý řetězec do něj chceme ukládat. K této velikosti ještě musíme připočíst 1, to z toho důvodu, že každý řetězec musí být ukončen "nulovým znakem" a v našem poli musí být místo i pro tento znak. Pro uložení řetězce "ahoj" bychom tedy museli vytvořit znakové pole o velikosti 5.

Tímto vytvoříme znakové pole s názvem str. Řetězec "ahoj" do něj vložíme takto (pouze při inicializaci):

char str[5] = "ahoj";

Řetězec, který chceme uložit do našeho znakového pole se musí dát do uvozovek. Přitom je důležité, aby se náš řetězec do tohoto pole vešel i s ukončovacím znakem. Jazyk C neprovádí žádnou kontrolu mezí a je možno přiřadit i příliš dlouhý řetězec, tedy samozřejmě s chybou a program zhavaruje dříve nebo později. To je velmi nepříjemná chyba, protože někdy to nemusí vadit vůbec, nicméně je to chyba programátora. Následující úsek programu je chybný:

char string[10] = "Mam rad programovani";

Ukončovací znak je automaticky překladačem přidán za tento řetězec. Existuje také řetězec nulové délky. Jeho "délka" je pak 0, ale v paměti zabírá 1 bajt, protože obsahuje minimálně ukončovací nulový znak. Řetězec nulové délky se dá přiřadit takto:

char string[10] = "";

Teď se dívám na starší díly a zjišťuju, že jsme moc nenačítali znakové konstanty a pravděpodobně ani neznáme funkce, které to dělají. Ještě to rychle zvládnem ne? :-)

char znak;

Vytvořili jsme si znakovou proměnnou a chceme, aby do ní uživatel zadal nějaké písmeno nebo jiný znak. Pozor, následující funkce nedá se použít pro čtení čísel (tedy dá, ale trochu jinak a složitěji). Číslice je totiž také jenom znak a má přiřazenu určitou hodnotu podle ASCII tabulky. Začíná nulou, ta má hodnotu 48 a devítka má hodnotu 57. Následující funkce tedy čte jeden znak zadaný na klávesnici a vrací jeho číselný ekvivalent z ASCII.

getchar()

Tato funkce po vyvolání čeká na stisknutí klávesnice. Jakmile je stisknuta klávesa, funkce getchar() vypíše její znak na obrazovku a vrátí hodnotu znaku té části programu, která jej vyvolala. Je definována v hlavičkovém souboru stdio.h. Naší proměnné znak tedy přiřadíme hodnotu z klávesnice pomocí getchar() takto:

znak = getchar();

Pro výpis tohoto znaku na obrazovku bychom potom použili příkazu printf se specifikátorem %c. Mohli bychom použít také %d, to by nám ale printf vypsala ASCII hodnotu tohoto znaku. Načtený znak se vypíše na obrazovku:

printf(" Zadany znak je: %c",znak);

Při používání funkce getchar() se však mohou objevit problémy, které by vám mohly hodně znepříjemnit život zjišťováním, kde ta chyba je. Funkce getchar() je naimplementována s tzv. řádkovým bufferem. To v praxi znamená, že vždy čeká, až uživatel zadá znak pro nový řádek (enter). Uživatel tedy může zadat i několik znaků a poté zmáčknout enter, ale funkce přečte jen první znak. Tady by ještě problém nebyl. Problém nastává v tom, že ostatní znaky zůstanou v bufferu uloženy a pokud by pak byla vyvolána například funkce scanf() pro zadání řetězce, uložené znaky z bufferu by se použily. Tím by v podstatě uživatel ztratil kontrolu nad programem. Proto existuje ještě jiná funkce pro čtení znaku zadaného z klávesnice a je deklarována v hlavičkovém souboru conio.h.

getche()

Narozdíl od getchar() nemá řádkový buffer. Je-li vyvolána, počká na zadání jednoho znaku a pak ihned končí a nečeká na další znaky nebo enter. Výhoda je v interaktivnosti. Její použití je stejné jako u getchar().

Fajn, malou odbočku máme za sebou a můžem se vrátit k našim řetězcům. Doposud jsme zadávali řetězce hned při překladu programu a vypisovaly by se pořád. Pro načtení jiného řetězce existuje funkce:

gets()

Malý program vytvoří znakové pole, načte do něj řetězec, který zadá uživatel a pak jej pomocí funkce printf vypíše na obrazovku. Jako argument funkce gets() se zadává jméno znakového pole, do kterého chceme řetězec načíst.

char str[50];
printf("Zadejte retezec kratsi nez 50 znaku.\n");
gets(str);
printf("Retezec je: %s",str);

Samotný řetězec by se dal pomocí printf() vypsat také jinak. Proč tomu tak je si ale vysvětlíme až při probírání ukazatelů.:

printf(str);

Tak to by na vysvětlení co to jsou řetězce mohlo stačit. Zatím umíme řetězce číst a vypisovat. Příště je o něco víc proberem. Budu popisovat různé funkce pro práci s nimi atd. Tak zatím. K.

Zpět

Programování v C | CZ 175/477 | Mapa stránek
Bc. Petr Klimánek, student Ostravské univerzity v Ostravě