Enrere Mòdul 6
Fonaments de programació. Llenguatge C/C++---
Pràctica  Exercicis
Pràctica d'ampliació

 
Resum Teòric

Cadenes de caràcters

Una cadena de caràcters és un vector de dades del tipus char que acaba en un caràcter NULL ('\0'). Per aquesta raó cal declarar vectors de caràcter amb un caràcter més que la cadena més llarga que volem emmagatzemar.

Per exemple, si volem un vector que emmagatzemi el missatge Això és una cadena, haurem de declarar un vector de la següent forma char str[19]

 

Valor inicial d'una cadena de caràcters

Podem posar valors inicials a una cadena de caràcters de dues formes diferents.

a) De la forma estàndard dels vectors, tal i com s'ha vist en el mòdul anterior. Cada caràcter va tancat entre cometes senzilles i els caràcters separats per cometes.

char str[5] = { 'h','o','l','a','\0'};

b) De la forma abreviada:

char str[5] = "hola";

En aquesta forma, tots els caràcters s'escriuen junts, tancats per dobles cometes i sense posar el caràcter '\'0' de fi de cadena que es posa automàticament.

En qualsevol de les dues formes es pot ometre la dimensió, és a dir, és vàlid tant:

char str[] = { 'h','o','l','a','\0'};

com:

char str[] = "hola";

En els dos casos, el compilador de C crearà automàticament un vector de cinc elements de caràcters.

 

Funcions de cadena. Entrada i sortida

La introducció d’una cadena en un programa té dues fases. La primera prepara l’espai de memòria suficient per al seu emmagatzematge, això s'aconsegueix amb la seva declaració. La segona fase consisteix en usar una funció per a capturar la cadena. Per a capturar cadenes directament del teclat es pot fer servir tres funcions la declaració de les quals estan a l'arxiu estàndard stdio.h. Una d'aquestes funcions ja s'ha vist amb anterioritat, es tracta de la funció scanf(). Unes altres funcions que es fan servir per omplir cadenes són gets() i fgets().

La funció gets() té el següent prototipus:

char *gets( char *var );

Aquesta funció rep caràcters de l'entrada estàndard (el teclat) i assigna els caràcters al vector de caràcters var[]. Quan es prem la tecla INTRO al finalitzar la cadena, s'envia un caràcter de nova línia que és traduït per aquesta funció per un caràcter nul de fi de cadena. És important remarcar que aquesta funció no fa comprovació que la cadena llegida tingui una mida igual o inferior a la mida reservada per emmagatzemar la variable. Una altra funció semblant que permet aquesta comprovació és la funció fgets().

La funció fgets(), té el següent protitipus:

char *fgets( char *var, int n, FILE *flux );

Quan s'utilitza aquesta funció per llegir cadenes del teclat, el tercer argument serà stdin, que correspon a l'entrada estàndard. A l'últim mòdul es tractarà amb més detall les entrades i sortides.

Aquesta última funció té l'avantatge que es pot garantitzar un nombre màxim de caràcters. La lectura es realitza fins que es troba un caràcter de nova línia (amb INTRO) o bé fins que es llegeixen n -1 caràcters (incloent-hi el caràcter de nova línia). 

La funció gets() reemplaça el caràcter de nova línia llegit pel teclat pel caràcter NULL ('\0'), en canvi la funció fgets() afegeix al caràcter de nova línia el caràcter NULL ('\0'). Les dues funcions retornen un punter a la cadena llegida o escrita, o bé el punter NULL si hi ha hagut un error. 

Per tal de mostrar el contingut d'una cadena pel teclat es fan servir les tres funcions associades respectivament a scanf(), gets() i fgets(), es tracta de: printf(), puts(), i fputs(). La primera d'elles ja s'ha vist amb anterioritat.

La funció puts() escriu el contingut del seu argument per pantalla reemplaçant el caràcter NULL pel caràcter de nova línia, en canvi, la funció fputs() no fa cap reemplaçament. Els prototipus d'aquestes dues funcions són:

int puts( const char *cadena );

int fputs( const char *cadena, FILE *flux );

En el cas de la funció fputs(), si la sortida és la sortida estàndard, es reemplaça el tercer argument per stdout.

Altres funcions de tractament de cadenes

Les funcions estàndards més importants que permeten treballar amb cadenes de caràcters i que estan definides a l'arxiu string.h són les que a continuació descriurem:

 
int strlen(const char *cadena)

Torna el nombre de caràcters de la cadena, sense comptar el caràcter '\0'

char *strcpy( char *cadesti,
                  const char *cadfont );

Copia el contingut de la cadena cadfont en la cadena cadesti. S'ha de tenir en compte que aquesta funció és diferent a l'assignació:

*cadesti=*cadfont

Aquesta última sentència només posaria el primer caràcter de caffont a cadesti, i a més no posa cap caràcter de fi de cadena.

En aquesta funció s'ha de tenir cura que la cadena cadfont no sigui més gran que la cadena cadesti.

Aquesta funció elimina el contingut previ de la cadena cadesti.

char *strncpy( char *cadesti,
                  const char *cadfont,
                         int n);

Copia el contingut dels n primers caràcters de cadfont en cadesti. Si n és més petit o igual que la longitud de la cadena cadfont, no s'afegeix cap caràcter NULL de fi de cadena. Si n és més gran que la longitud de la cadena cadfont, la cadena cadesti, s'omple de caràcters NULL fins a la longitud n. Aquesta funció, com l'anterior, no fa comprovació de longitud i, per tant, el comportament pot ser desastrós si la longitud de la cadena cadfont i n són més grans que la longitud de la cadena cafdesti.

char *strcat( char *cadesti,
                       const char *cadfont );

Afegeix la cadena cadfont al final de la cadena cadesti. La cadena cadfont no canvia el seu contingut.

char *strncat( char *cadesti,
                       const char *cadfont,
                       
int n );

Afegeix n caràcters de la cadena cadfont al final de la cadena cadesti.

En aquesta funció i en l'anterior el primer caràcter afegit substitueix al caràcter fi de cadena anterior. Aquest caràcter és afegit al final.

int strcmp( char *cad1, char *cad2 );

Aquesta funció compara les cadenes cad1 i cad2. Torna un 0 si coincideixen i un número diferent de 0 si no coincideixen. La comparació es fa caràcter a caràcter fins trobar un caràcter que no coincideix o el caràcter fi de cadena.

int strncmp( char *cad1, char *cad2, int n );

Compara els n primers caràcters de les cadenes cad1 i cad2. La comparació es fa de la mateixa forma que a la funció anterior.

int _stricmp( const char *cad1, const char *cad2 );

int _strnicmp( const char *cad1, const char *cad2,int n );

Aquestes dues funcions són similars a les dues anteriors amb la diferència que en la comparació no distingeix entre majúscules i minúscules.

El símbol _ indica que aquestes funcions no corresponen a l'estàndard ANSI, no obstant això, també es poden fer servir en Visual C++ sense aquest caràcter.

char *strchr( const char *cad, int c );

Aquesta funció retorna un punter a la primera ocurrència del caràcter c en la cadena cad. Si aquest caràcter no hi és torna un NULL.

char *strrchr( const char *cad, int c );

Aquesta funció retorna un punter a l'última ocurrència del caràcter c en la cadena cad. Si aquest caràcter no hi és torna un NULL.

char *strstr( const char *cad, const char *subcad );

Aquesta funció retorna un punter a la primera ocurrència de la subcadena subcad en la cadena cad o bé un punter a NULL si no es troba.

char *strpbrk( const char *cad, const char *subcad );

Aquesta funció retorna un punter a la primera ocurrència de qualsevol dels caràcters de subcad en la cadena cad o bé un punter a NULL.

A més d'aquestes funcions, n'hi ha altres que poden ser útils per al tractament de cadenes. Les declaracions d'aquestes funcions estan al fitxer capçalera ctype.h:

 
int isalpha(int c)

Torna un valor diferent de 0 si c és una lletra i 0 si no ho és.

int isupper(int c)

Torna un valor diferent de 0 si c és una lletra majúscula i 0 si no ho és.

int islower(int c)

Torna un valor diferent de 0 si c és una lletra minúscula i 0 si no ho és.

int isdigit(int c)

Torna un valor diferent de 0 si c és un dígit i 0 si no ho és.

int isalnum (int c)

Torna un valor diferent de 0 si c és una lletra o un dígit  i 0 si no ho és.

int isspace( int c)

Torna un valor diferent de 0 si c és un espai, un tabulador o el caràcter de nova línia i 0 si no és cap d'aquests caràcters.