Funkcie pre prácu s reťazcami

Práca s reťazcami je podporovaná celým radom štandardných funkcií, ktoré sa vyskytujú prakticky vo všetkých implementáciách jazyka C. Sú to funkcie pre kopírovanie, spájanie, porovnávanie, vyhľadávanie a určenie dĺžky reťazca. V nižšie uvedených základných funkciách sú parametre s, s1 a s2 typu char * (smerník na char), c je typu int a n typu unsigned int. Všetky funkcie sú definované v hlavičkovom súbore .

int strcmp(char *s1, char *s2) (string compare)

- lexikograficky porovnáva reťazce s1 a s2. Vracia číslo >0, ==0, resp. <0 podľa toho, či s1 > , =, resp. < ako s2.

int strncmp(char *s1, char *s2, unsigned int n) (string max n compare

- lexikograficky porovnáva maximálne n znakov reťazcov s1 a s2. Vracia číslo >0, ==0, resp. <0 podľa toho, či s1 > , =, resp. < s2.

unsigned int strlen(char *s) (string length)

- vracia dĺžku reťazca so smerníkom s (bez binárnej koncovej nuly).

char *strcpy(char *s1, char *s2) (string copy)

- kopíruje jednotlivé znaky reťazca s2 do s1, vrátane koncovej nuly. Vracia smerník na reťazec s1, obsah ktorého sa prepíše. Dĺžka s1 musí byť dostatočná.

char *strncpy(char *s1, char *s2, unsigned int n) (string max n copy)

- kopíruje jednotlivé znaky reťazca s2 do s1, vrátane koncovej nuly, ak s2 je kratšie ako n. Inak sa kopíruje iba prvých n znakov reťazca s2 a s1 nie je zakončené binárnou nulou. Vracia smerník na reťazec s1, obsah ktorého sa prepíše. Dĺžka s1 musí byť dostatočná.

char *strcat(char *s1, char *s2) (string concatenation)

- pripojí jednotlivé znaky reťazca s2 za reťazec s1, vrátane koncovej nuly (pôvodná koncová nula v s1 je prepísaná prvým znakom s2). Vracia smerník na reťazec s1, obsah ktorého sa prepíše. Reťazec s2 ostáva bez zmeny. Dĺžka s1 musí byť dostatočná.

char *strncat(char *s1, char *s2, unsigned int n) (string max n concatenation)

Pripojí maximálne n znakov reťazca s2 za reťazec s1 (pôvodná koncová nula v s1 je prepísaná prvým znakom s2, za posledný znak s1 doplní novú koncovú nulu). Vracia smerník na reťazec s1, obsah ktorého sa prepíše. Reťazec s2 ostáva bez zmeny. Dĺžka s1 musí byť dostatočná.

char *strchr(char *s, int c) (string search character)

- vracia smerník na prvý výskyt znaku c v reťazci s. Ak sa znak c v reťazci s nevyskytuje, vracia hodnotu NULL.

char *strrchr(char *s, int c) (string right search character)

Vracia smerník na posledný výskyt znaku c v reťazci s, t.j. na prvý výskyt znaku c sprava. Ak sa znak c v reťazci s nevyskytuje, vracia hodnotu NULL.

char *strstr(char *s1, char *s2) (string search string)

- vracia smerník na prvý výskyt reťazca s2 v reťazci s1. Ak sa reťazec s2 v reťazci s1 nevyskytuje, vracia NULL.

Všetky funkcie je možné jednoducho zapísať v jazyku C. Funkciu pre určenie dĺžky reťazca pozri príklad v kap. 4.2. Funkciu pre pripojenie reťazca s2 za s1 možno zapísať takto :

char *strcat(char *s1, char *s2)
{
char *p;

p=s1;
while (*p++); /* nastavi smernik na koniec s1 */
--p; /* nastavi smernik na koncovu nulu */
while (*p++ = *s2++); /* prikopíruje s2 za s1 */
return (s1);
}

Ďalší príklad ilustruje vyhľadanie podreťazca s2 v reťazci s1 :

/* priklad pr7_1.c vyhľadanie podreťazca */

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

void main(void)
{
char *s1 = "Text v ktorom hladame vzor";
char *s2 = "vzor", *pom;
pom = strstr(s1, s2);
if (pom != NULL)
printf("Podretazec %s najdeny v %s na pozicii %d\n", pom,s1,pom - s1);
else
printf("Podretazec %s sa v %s nenachdza\n",pom,s1);
}

Reťazec je možné spracovávať i ako pole po jednotlivých znakoch, vrátane koncovej nuly, napr. :

s[0]='A'; s[1]='B'; s[2]='C'; s[3]='\0';
printf("%s %c %s",s,*(s+1),s+1);

Príkaz printf vytlačí ABC B BC (smerníková aritmetika). Najčastejší spôsob inicializácie reťazca využíva funkciu strcpy.

V ďalšom príklade program číta reťazec, vytlačí ho od konca a určí počet znakov 'a' v tomto reťazci :

/* priklad pr7_2.c čítanie a tlač reťazca, počet znakov */

#include <stdio.h>

int charcount(char *s, char c);

void main(void)
{
char a='a',b,c[80];
int i=-1;

printf("Zadaj retazec = ");
while((c[++i]=getchar()) != '\n');
c[i]='\0';
printf("Retazec %s v opacnom poradi :\n",c);
while(i) putchar(c[i--]); printf("\nobsahuje %d vyskytov znaku %c\n", charcount(c,a));
}

int charcount(char *s, char c)
{
int count=0;

while(*s!='\0') if(*s++ == c) count++;
return(count);
}

Načítanie reťazca, vymazanie všetkých znakov 'a' v tomto reťazci a vytlačenie upraveného reťazca realizuje nasledujúci príklad:

/* priklad pr7_3.c čítanie a tlač reťazca, vyhodit znaky */

#include <stdio.h>

void remchar(char *s, char c);
void main(void)
{
char a='a',c[80];

printf("Zadaj retazec = ");
scanf("%s",c);
printf("Retazec : %s\n",c);
remchar(c,a); printf("Retazec bez znakov %c :%s\n",c,a);
}

void remchar(char *s, char c)
{
char *pom=s;
while(*s!='\0')
{
if(*s++ != c) *pom++ = *s;
s++;
}
*pom = '\0';
}

Posledný príklad v tejto časti uvádza porovnanie mechanizmu vytvorenia reťazca príkazom sprintf v prvej časti príkladu a štandardným spôsobom s využitím funkcií pre prácu s reťazcami v druhej časti :

/* priklad pr7_4.c vstup - vystup retazca formatovy retazec */

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

void main(void)
{
char s2[30],s3[30];
int i;

/* vytvorenie retazca prikazom sprintf*/
printf("Vstup retazca:");
gets(s2);
i=strlen(s2);
switch(i)
{
case 1:
{
sprintf(s3,"Dlzka <%s> je %d znak",i);
break;
}
case 2:
case 3:
case 4:
{
sprintf(s3,"Dlzka <%s> je %d znaky",i);
break;
}
case 0:
default:
{
sprintf(s3,"Dlzka <%s> je %d znakov",i);
break;
}
}
printf("%s\n",s3);

/* klasicky pristup - standardne funkcie */
strcpy(s3,"Dlzka");
strcat(s3,s2);
strcat(s3,"> je ");
sprintf(s2,"%d",i);
strcat(s3,s2);
strcat(s3," znak");
switch(i)
{
case 2:
case 3:
case 4:
{
strcat(s3,"y");
break;
}
case 0:
default:
{
strcat(s3,"ov");
break;
}
}
printf("%s\n",s3);
}