#9 Práce s textem

Právě dnes Vám přinášíme další díl našeho kurzu programování v jazyce C. V této lekci se budeme zabývat řetězci, zejména používání vestavěných funkcí pro práci s textem, kterých není málo a proto si ukážeme jen ty nejpoužívanější nebo spíše nejužitečnější pro základní práci s řetězci.

Poprvé jsme se o řetězcích zmínili v 6. lekci, kde jsme si ukázali jejich deklaraci, vstup do programu a následné vypsání. Nyní si informace o řetězcích trochu rozšíříme.

Charakteristika řetězců

Jak jsme si již definovali v předešlé lekci (6. lekce), že řetězec je posloupnost znaků. V jazyce C bývají zapsané jako pole znaků (charů). Každý řetězec je ukončen tzv. Binární nulou. Právě díky ukončovací nule si nemusíme pamatovat velikost pole. Pole znaků procházíme pouze do výskytu ukončovací nuly. Je možné nulu posouvat na nižší úroveň v poli, čímž se řetězec zkracuje. Znaky za ukončovací nulou nejsou zpravidla dostupná, ale při pokusu o jejich vypsání se zobrazí jakési „smetí“ z paměti.

Deklarace řetězce

char string[10]; //9 znaku + ukoncovaci nula

Pokud při deklaraci rovnou přiřadíme i nějaký řetězec, velikost pole se nastaví podle počtu znaků + ukončovací nula.

char string[] = "text"; //velikost pole = 5

Inicializace řetězce

Rozdíl v inicializaci pole a řetězce:

char str1[]="abc"; //inicializace pomoci retezcove konstanty
char str2[]={'a','b','c'}; //inicializace pole znak po znaku

Druhý zápis nevloží nakonec pole ukončovací nulu. Pro správnost musíme přidat i nulu jako 4. prvek pole.

char str2[]={'a','b','c', 0};

Pokud použijeme funkci scanf pro načtení řetězce tak syntaxe vypadá následovně:

scanf("%s", string);

Víme, že u funkce scanf se k proměnné přidává operátor reference, aby fungovala správně, jelikož proměnná typu řetězec obsahuje adresu tak se tento operátor nepřidává.

Operace s řetězci

char string[] = “Lorem ipsum”;

Vypsání určitého znaku v řetězci lze bud pomocí operátoru hranaté závorky, kde se vypíše daný prvek v poli, nebo pomocí ukazatelové aritmetiky nastavíme ukazatel na konkrétní adresu a pomocí operátoru dereference vypíšeme obsah paměti na této adrese.

printf("%c\n", string[6]);
printf("%c\n", *(string+6));

Můžeme část řetězce vložit do nového, opět za pomoci ukazatele.

char* string2 = string + 6; //string2 = "ipsum"

Můžeme řetězec zkrátit vložením ukončovací nuly. Zapsáni nuly je možné dvěma způsoby, je jedno který zvolíte.

string[5] = 0;
string[5] = '\0';

Pole řetězců

Je to pole kde typ jednotlivého prvku pole je ukazatel na řetězec (char*). Nejčastější použití takového pole je pro řadu konstantních řetězců.

char* OnlineKurzy[] = {"Lekce VBA","Lekce Pascalu","Kurz C","Webdesign"};

Funkce pro práci s řetězci

Nejprve si ukážeme pár důležitých funkcí, které se nacházejí v knihovně string.h

Funkce strlen

Je to velice používaná funkce, která vrací počet znaků v řetězci. Na příkladu vidíme rozdíl mezi sizeof a strlen. V příkladu je i test ukončovací nuly, zda se opravdu v řetězci nachází.

#include <stdio.h>
#include <string.h>

int main(void)
{
    char string[] = "Lorem ipsum";
    printf("%s\n", string);
    printf("sizeof: %d\nstrlen: %d\n",sizeof(string),strlen(string));
    string[5] = '\0'; //vlozime ukoncovaci nulu doprostred retezce
    printf("%s\n", string);
    printf("sizeof: %d\nstrlen: %d\n\n",sizeof(string),strlen(string));

    printf("vypisuju ukoncovaci nulu jako znak:%c(vlozi mezeru)\n", string[11]);
    printf("vypisuju ukoncovaci nulu jako cislo:%d(vlozi cislo)\n", string[11]);

    return 0;
}

Pokud chceme nulu vypsat samostatně jako znak tak se na výpisu objeví mezera, při výpisu celého řetězce se tato mezera neobjeví, jelikož se vypisují pouze znaky před ukončovací nulou.

U funkce strlen opravdu vidíme, že řetězec má délku 11, ale funkce sizeof nám vrací číslo o 1 větší a to proto, že funkce ukazuje kolik je potřeba bytů na uchování tohoto řetězce v paměti. Víme, že na uložení jednoho znaku potřebujeme právě 1 byte a ten 12. byte navíc je právě pro ukončovací nulu.

Funkce strcpy

Slouží k překopírování jednoho řetězce do druhého.

strcpy(retezec1,retezec2);

Dle znázornění se zkopíruje retezec2 do retezce1. Důležité pravidlo pro použití této funkce je, že retezec1 musí být dostatečně velký, aby byl schopen uložit do sebe retezec2.

Funkce strcat

Tato funkce umožňuje spojit dva řetězce v jeden.

char str[256] = "Lorem";
printf("%s\n",strcat(str,"Ipsum"));

Výsledek bude vypadat: LoremIpsum.

Pravidlo pro tuto funkci je, že opět první řetězec musí mít dostatečnou velikost a to: (délka prvního řetězce) + (délka druhého řetězce) + 1 (ukončovací nula)

Funkce strcmp

Pro porovnání dvou řetězců se používá tato funkce.

strcmp(retezec1,retezec2);

Funkce vrací celočíselnou hodnotu:

  • hodnota 0 – vrací, jestliže jsou oba řetězce shodné
  • hodnota >0 – vrací, pokud první řetězec je větší než druhý
  • hodnota <0 – vrací, pokud první řetězec je menší než druhý

Výsledky jsou vyhodnoceny na základě uspořádání znaků v ASCII tabulce. Pokud tedy použijeme toto porovnání:

strcmp("A","a");

Hodnota velkých písmen je v ASCII tabulce před malými písmeny, tudíž funkce vyhodnotí výsledek na záporný.

Funkce strchr

Jedná se o vyhledávací funkci, která zjišťuje, zda řetězec obsahuje hledaný znak.

strchr(retezec,znak);

Pokud se hledaný znak v řetězci nachází potom funkce vrací hodnotu v podobě ukazatele na prvně nalezený znak, v opačném případě vrací hodnotu NULL.

Funkce strstr

Obdobná funkce jako předchozí, akorát s tím rozdílem, že funkce vyhledává, zda se v prvních řetězci nachází řetězec druhý. Pokud se takový řetězec najde, funkce vrací ukazatel na první výskyt řetězce.

Znakové funkce

V následující tabulce si ukážeme několik funkcí, které zjišťují charakteristiku znaku, všechny tyto funkce se nacházejí v knihovně ctype.h. Všechny funkce mají jeden parametr a to znak (char). Návratová hodnota pro všechny funkce je stejná, mohou nastat pouze 2 případy:

  • Funkce vrátí číslo různé od nuly pro PRAVDU
  • Funkce vrátí číslo 0 pro NEPRAVDU
Funkce Popis Znaky 1
isalnum(char) Je znak písmeno nebo číslo? A – Z, a – z, 0 – 9
isalpha(char) Je znak písmeno? A – Z, a – z
isblank(char) Je znak prádný? tabulátor (‚\t‘), mezera (‚ ‚)
iscntrl(char) Je znak řídící? znaky s ASCII hodnotu < 32 a znak s hodnoutou 127
isdigit(char) Je znak číslo? 0 – 9
isgraph(char) Má znak grafické znázornění? 0 – 9, A – Z, a – z, všechny speciální znaky
islower(char) Je znak malé písmeno? a – z
isprint(char) Je znak tisknutelný? mezera, 0 – 9, A – Z, a – z, všechny speciální znaky
ispunct(char) Je znak speciální? !“#$%&'()*+,-./:;<=>?@[\]^_`{|}~
isspace(char) Je znak „bílý“? tabulátor (‚\t‘), mezera (‚ ‚), nový řádek (‚\n‘), návrat vozíku (‚\r‘), vertikální tabulátor (‚\v‘), konec stránky (‚\f‘)
isupper(char) Je znak velké písmeno? A – Z
isxdigit(char) Je znak hexadecimalní číslo? 0 – 9, A – F, a – f

1) Tato položka zobrazuje znaky, u kterých daná funkce vyhodnotí znak na pravdivý

V knihovně ctype.h se nacházejí jěště 2 funkce, které převádějí znak buď na velké písmeno nebo naopak na malé. Ještě jednou zdůrazňuji, že převádejí znak nikoliv celé slovo (řetězec), pokud bychom chtěli použít jednu z těchto funkcí na celém řetězci, jednoduše použijeme cyklus, který projde řetězec znak po znaku a upraví jej podle potřeby.

Funkce Popis
tolower(char) převede velké písmeno na malé
toupper(char) převede malé písmeno na velké

 

K dnešní lekci to bude vše, doufám že jste se zase něco dozvěděli, můžete i články sdílet na sociálních sítích a podobně. V následujícím článku se zaměříme na soubory.

Napsat komentář