Knihovna string.h

V předchozím výkladu syntaxe jazyka C jsem využíval některých standardních knihoven a jejich funkcí, například printf() a scanf(). Další funkce, se kterými jste se seznámili, byli například funkce rand() a srand(), nebo třeba funkce atoi(). Mimoto jsme se setkali i s funkcemi nestandardními, implementačně závislými (delay() a usleep()).

V této a dalších kapitolách se budu věnovat nejpoužívanějším standardním funkcím ze standardních knihoven. Nebudu vypisovat všechny funkce (a ani všechny knihovny). Jejich popis, a mnohde i příklady použití, najdete v dokumentaci k překladači, nebo v manuálových stránkách (na Linuxu).

Začnu něčím jednodušším, a to funkcemi pracujícími s řetězci. Tyto funkce jsou definovány v knihovně <string.h>. Jen připomínám, že řetězce jsou datové pole obsahující znaky, které jsou zakončeny zarážkou '\0' (nulový bajt).

Výčet funkcí

Vzhledem ke zjednodušení popisu se nebudu vyjadřovat exaktně a například místo „řetězec, na který ukazuje ptr“ budu psát „řetězec ptr“. Doufám, že tím nezpůsobím příliš zmatků :-). A ještě připomínám, že typ size_t je ekvivalent typu unsigned int, který by měl být dostatečně velký na to, aby byl schopný adresovat celou délku i toho největšího pole.

Pokud (standardní) funkce někam kopírují data, většinou nekontrolují, zda na to mají dostatek místa. To musíte zajistit vy, jako programátoři. Jinak se může snadno stát, že program skončí kvůli „neoprávněnému přístupu do paměti“.

char *strcat(char *dest, const char *src);
Funkce připojí řetězec src k řetězci dest (na jeho konec). Funkce vrací ukazatel na řetězec dest.
char *strncat(char *dest, const char *src, size_t n);
Jako funkce strcat, ale přidá jen n znaků z src. Tato funkce je bezpečnější z hlediska možného "přetečení" (pokus zapisovat více dat, než jakou má velikost dest). Měli byste spíše používat tuto verzi.
Porovnává řetězce s1 a s2. Pokud je s1 < s2 pak vrací hodnotu menší než 0, pokud jsou si rovny, pak vrací 0, pokud je s1 > s2 pak vrací hodnotu větší jak 0.
Jako strcmp(), porovnává však jenom n znaků.
char *strcpy(char *dest, const char *src);
Zkopíruje řetězec src do řetězce dest. Vrací ukazatel na dest.
char *strncpy(char *dest, const char *src, size_t n);
Jako strcpy(), ale zkopíruje maximálně n znaků. (Je-li jich právně n, nepřidá zarážku).
Vrací délku řetězce s.
Vrací ukazatel na první pozici, kde se vyskytuje znak c, nebo NULL v případě, že jej nenajde. (Nenechte se zmást, že znak c je typu int a ne char, má to tak být).
To samé jako strchr(), ale hledá první výskyt zprava.
char *strstr(const char *haystack, const char *needle);
Vrací ukazatel na první výskyt řetězce needle v řetězci haystack. Pokud jej nenajde, vrací NULL.
Vrací počet počátečních znaků, ve kterých řetězec s obsahuje znaky z řetězce accept (v libovolném pořadí).
Vrací počet znaků, ve kterých řetězec s neobsahuje žádný znak z řetězce reject.

Příklad použití funkcí

Nemusím snad říkat, že je třeba v programu deklarovat knihovnu <string.h>, pokud chcete používat funkce z této knihovny.

V příkladu si všimněte především použití funkce strncpy(). Díky zjištění délky prvního řetězce a velikosti pole1 jsem mohl zajistit, aby se z pole2 nezkopírovalo více znaků, než kolik se jich do pole1 vejde.

  1. /*------------------------------------------------*/
  2. /* c19/retezce.c                                  */
  3. #define _CRT_SECURE_NO_WARNINGS
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. int main(void)
  8. {
  9.     char c, *ch, pole1[81], pole2[81];
  10.     int x;
  11.  
  12.     printf("Zadejte jeden znak a stisknete ENTER: ");
  13.     scanf("%c", &c);
  14.     printf("Zadejte prvni retezec: ");
  15.     scanf("%80s", pole1);
  16.     printf("Zadejte druhy retezec: ");
  17.     scanf("%80s", pole2);
  18.  
  19.     x = strcmp(pole1, pole2);
  20.     if (x < 0)
  21.         printf("pole1 < pole2\n");
  22.     else if (x == 0)
  23.         printf("pole1 = pole2\n");
  24.     else
  25.         printf("pole1 > pole2\n");
  26.  
  27.     printf("Prvnich %i znaku se %s\n", 5,
  28.            !strncmp(pole1, pole2, 5) ? "shoduje" : "neshoduje");
  29.     printf("Prvnich %u znaku pole1 je v pole2\n", strspn(pole1, pole2));
  30.  
  31.     ch = strchr(pole1, c);
  32.     if (ch == NULL)
  33.         printf("Znak %c se v retezci \"%s\" nenachazi\n", c, pole1);
  34.     else
  35.         printf("pole1 od znaku %c: %s\n", c, ch);
  36.  
  37.     x = strlen(pole1);
  38.     printf("Delka prvniho retezce: %u\n", x);
  39.     strncat(pole1, pole2, sizeof(pole1) - x - 1);
  40.     printf("Spojeni: %s\n", pole1);
  41.  
  42.     return 0;
  43. }
  44.  
  45. /*------------------------------------------------*/
Visual Studio

Makro _CRT_SECURE_NO_WARNINGS je tu kvůli funkci scanf(), viz scanf().

Možný výstup z programu:

Zadejte jeden znak a stisknete ENTER: y
Zadejte prvni retezec: DlouhyRetezec
Zadejte druhy retezec: Dlouze
pole1 < pole2                   
Prvnich 5 znaku se neshoduje
Prvnich 4 znaku pole1 je v pole2
pole1 od znaku y: yRetezec
Delka prvniho retezce: 13
Spojeni: DlouhyRetezecDlouze

Platí, že pole1 < pole2, protože h < z.

Komentář Hlášení chyby
Created: 29.8.2003
Last updated: 22.6.2014
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..