Sunteți pe pagina 1din 24

Capitolul 9

Şiruri de caractere
 Declarare, iniţializare, constante şir de caractere
 Operaţii la nivel de caracter
 Operaţii cu şiruri de caractere

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 147
9.1 Declarare, iniţializare, constante şir de caractere

În cadrul programelor prezentate până în acest moment, am folosit valori de tip


caracter doar sub una dintre următoarele forme:

printf(“Bună ziua!”);

şir de caractere (litere, numere, caractere speciale)

tipul caracter char c;


c = ‘a’; /* corect */
c = “a”; /* greşit, nu sunt de acelaşi tip! Vom afla in curând
de ce...*/

tablou de caractere char cuvânt [ ] = {‘s’, ‘a’, ‘l’, ‘u’, ‘t’, ‘!’};

se rezervă 6 octeţi, datorită iniţializării.

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 147
Folosind doar cunoştinţele de programare deja acumulate, scrierea unei funcţii care să
concateneze 2 şiruri de caractere (şir1 şi şir2), s-ar putea face, de exemplu, numai cu
condiţia ca „lungimile” celor 2 şiruri (numărul lor de elemente) să fie cunoscute:
Demonstratie: 9_148.C
void concat (char rez[ ], char sir1[ ], int n1, char sir2[ ], int n2)
{ int i;
for( i=0; i<n1; i++) rez[i] = sir1[i]; /* copiază şir1 în rez*/
for( i=0; i<n2; i++) rez[n1+i] = sir2[i]; /* copiază şir2 în rez în continuarea lui şir1*/
}
#include <stdio.h>
int main()
{ char s1[5] = {‘F’, ‘u’, ‘n’, ‘c’, ‘ţ’};
char s2[7] = {‘i’, ‘o’, ‘n’, ‘e’, ‘a’, ‘z’, ‘ă’};
char s3[20]; /*dezavantaj: trebuie specificată o dimensiune acoperitoare*/
int i, n, n1=5, n2=7;
n=n1+n2;
concat(s3, s1, n1, s2, n2);
for( i=0; i<n; i++)
printf(“%c”, s3[i]);
printf(“\n”);
return 0;
}

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 148
Particularitate:

Se poate folosi un caracter special care să marcheze sfârşitul unui şir de


caractere:

 se numeşte caracter nul


 are codul ASCII asociat 0 (zero)
 se scrie în forma ’\0’ (constantă de tip caracter)
 rol - arată unde se termină informaţia utilă stocată într-o variabilă “şir de
caractere” (de tip tablou de caractere).

De exemplu, dacă într-un tablou de maximum 20 de caractere se pun valori numai pe


primele 6 poziţii, în cea de-a şaptea poziţie trebuie pus caracterul nul:
char cuvânt [20]={‘s’, ‘a’, ‘l’, ‘u’, ‘t’, ‘!’, ‘\0’}; /*6 caractere utile, plus caracterul nul*/

Caracterul nul este recunoscut şi folosit de majoritatea funcţiilor de bibliotecă


destinate lucrului cu şiruri de caractere (descrise în string.h, de exemplu).

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 148
Exemple de utilizare a caracterului nul: scrierea unei funcţii ce determină numărul
de caractere utile dintr-un şir (mai multe variante de implementare).

Demonstratie: 9_149.C
int lung_sir( char sir[ ] )
{ int k = 0;
while( sir[k] != ‘\0’ ) echivalent cu while( sir[k] ) ++k;
++k;
return k; vezi corespondenţa 0 --- ’\0’
}

sau

int lung_sir( char sir[ ] )


{ int k = 0;
while( sir[k++] ) echivalent cu while( sir[k++] ) continue;
; /* instructiune vidă*/
return (k-1); /*deoarece k indica pozitia caracterului nul, aici*/
}

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 149
sau

int lung_sir( char sir[ ] )


{ int k;
for( k=0 ; sir[k] ; k++ )
; /* instructiune vidă sau continue;*/
return k;
}

sau

int lung_sir( char *sir )


{ int k;
for( k=0 ; *sir++ ; k++ )
; /* instructiune vidă sau continue;*/
return k;
}

sau
Folosirea funcţiei din biblioteca string.h, strlen(sir_caractere), care
returnează ca rezultat lungimea şirului de caractere fară caracterul nul, de
sfârşit. Într-o secţiune separată a acestui capitol vor fi detaliate câteva dintre
cele mai folosite funcţii din această bibliotecă a compilatorului C.
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 149
Constante şir de caractere

 “Salut” – este o constantă şir de caractere reprezentată intern pe 5+1 octeţi


(caracterul nul este adăugat automat de compilator) => lungimea în memorie este
mai mare cu 1 decât numărul de caractere dintre simbolurile ghilimele.

 Situatie des intalnita in programe:


char *p;
p = “a”; /*CORECT, adresa de inceput a sirului de caractere*/
/*NU copiere sir caractere ci atribuirea unei adrese*/

 Constanta sir de caractere este memorata (implicit) in zona heap (alocare


dinamica)
 Adresa de inceput a acelei zone este inscrisa, prin instructiunea de atribuire,
in variabila pointer p (adresa primului caracter din sir).

 Una dintre „diferenţele de tip” generate de utilizarea constantelor caracter şi a


celor şir de caractere:
char c;
c = ‘a’; /* 1 octet, OK */
c = “a”; /* GRESIT- intr-o variabila de tip char incerc sa pun o valoare
pointer*/
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 150
Iniţializarea tablourilor de caractere

char cuvant[ ] = {“Salut”};

sau echivalent cu

char cuvant[ ] = “Salut”;

char cuvant[ ] = {‘S’, ‘a’, ‘l’, ‘u’, ‘t’, ‘\0’}; => dimensiune 6

Obs. Se poate dimensiona explicit tabloul de caractere:

char cuvant[6]=“Salut”;

DAR… dimensiunea tabloului trebuie sa ia in considerare si caracterul nul, altfel se


pierd caractere!

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 150
Şirul nul de caractere
este un şir de caractere care conţine doar caracterul nul ( ‘\0’ )

 Exemplu:

char cuvant[10] = ””; /*se scriu doar ghilimelele (fără spaţiu intre ele)*/

 Pentru introducerea de la tastatură a unui sir nul, se apasă doar ENTER.

 Utilitatea - va fi exemplificata intr-o alta sectiune a acestui capitol.

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 151
Secvenţe escape (caractere speciale)

Sunt interpretate ca o singură constantă de tip caracter (o valoare de tip char, nu un


şir de caractere!), deşi pentru scrierea lor se foloseşte o combinaţie de simboluri:

\a Alertă sonoră \v Tab vertical


\b Backspace \\ Backslash
\f Form feed \” Ghilimele
\n Linie nouă \’ Apostrof
\r CR \? Semnul întrebării
\t tab
\0nn Valoare octală nn Pentru a include în şir caractere care
\xnn Valoare hexa nn nu sunt disponibile la tastatură (se scrie
codul ASCII al caracterului respectiv)

Demonstratie: 9_151_152.C

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 151
Scrierea unei constante şir de caractere pe linii successive

 Se realizeaza prin utilizarea caracterului backslash, adica \, la sfarsitul fiecarei linii,


ca in exemplul urmator:

char exemplu[ ] = {“AcestaEsteUn\


ExempluDeScriere”};

se continua scrierea caracterelor din prima poziţie a liniei, altfel se vor


include in sir toate eventualele caractere spatiu...

 O alta varianta: “spargerea” constantei şir de caractere în mai multe şiruri


adiacente, conform principiului “Unu” “Doi” “Trei” ≡ “UnuDoiTrei”

char exemplu[ ] = {“AcestaEsteUn”


“ExempluDeScriere”};

in acest caz, nu are importanta faptul ca scrierea se


face sau nu din prima pozitie a liniei urmatoare.

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 152
9.2 Operaţii la nivel de caracter
 Citire de la tastatură
 Scriere pe ecran
 Comparaţii şi operaţii aritmetice
9.2.1 Citire de la tastatură
char car;
scanf(“%c”, &car); (obisnuit) dar uneori apar probleme daca in program
trebuie citite si date numerice (vezi Exemplu – pe slide-ul urmator – prezentat
„live” la curs!)
int getchar(void) => funcţie specializată, nu necesită format de citire.
Caracterul citit este pus in octetul mai puţin semnificativ (pentru
compatibilitatea cu versiunile de compilatoare mai vechi).
Ex: car = getchar(); aşteaptă ENTER pentru a se executa

int getche(void) => spre deosebire de getchar(), preia caracterul tastat fără a
mai aştepta ENTER. Nu face parte din stdio.h, ci din
conio.h

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 152
Demonstratie: sir_scanf.C

Exemplu cu functionare defectuoasa:

#include <stdio.h>
#include <conio.h>
int main(void)
{ int i;
float x;
char car;
car='D';
while(car=='D' || car=='d')
{printf("Tastati 2 numere: unul intreg si unul real\n");
scanf("%d%f", &i, &x);
printf("Numerele tastate au fost: %d si %f\n", i, x);
printf("Continuati? (D/N):");
scanf("%c",&car);
}
return 0;
}

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 153
Acelasi exemplu, dar cu variante de scriere: Demonstratie: sir_scanf_bis.C

#include <stdio.h>
#include <conio.h>
int main(void)
{ int i;
float x;
char car;
car='D';
while(car=='D' || car=='d')
{printf("Tastati 2 numere: unul intreg si unul real\n");
scanf("%d%f", &i, &x);
printf("Numerele tastate au fost: %d si %f\n", i, x);
printf("Continuati? (D/N):");
/*fflush(stdin);*/
/*scanf("%c",&car);*/ /*Apare singura --> functionare defectuoasa!
Apare precedata de fflush(stdin); --> functionare OK*/
/*scanf("%c%c",&car,&car);*/ /*Apare in locul celor 2 anterioare --> OK*/
/*car=getche();*/ /*Apare singura --> functionare OK */
}
return 0;
}

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 153
9.2.2 Scriere pe ecran

printf(“%c”, car);

int putchar(int c); scrie un caracter pe ecran – returnează caracterul scris


Ex: putchar(car);

9.2.3 Comparaţii şi operaţii aritmetice

În limbajul C, o constantă sau o variabilă de tip char care apare într-o expresie este
convertită automat la valoarea int ce corespunde reprezentării interne (ASCII) a
caracterului (numărul de ordine în set).

În setul de caractere ASCII se respectă ordinea numerică şi cea lexicografică.

Din acest motiv, expresia car>=‘a’ && car<=‘z’ este CORECTĂ şi verifică faptul că
variabila car este sau nu caracter literă mică.

Formă de scriere echivalentă: car>=97 && car<=122 (coduri ASCII, in baza 10)

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 154
Conversiile automate caracter-cod ASCII

 permit scrierea unor fragmente de program de tipul:


char x = ‘a’;
printf(“Caracterul %c are numarul de ordine %d in setul ASCII”, x, x);
Ca efect, pe ecran se va afisa textul:
Caracterul a are numarul de ordine 97 in setul ASCII

 permit folosirea valorilor de tip char in operatii aritmetice.


car = ‘a’ + 1; => este echivalent cu car = ‘b’; deoarece adunarea se realizează
folosindu-se valorile întregi (codurile ASCII) asociate caracterelor
 exemplu interesant:

char car = ‘8’;


int i;
i = car – ‘0’; => se converteşte caracterul ’8’ în valoarea intreaga 8

8 = 56 – 48;

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 154
Ex: funcţie de conversie a unui şir de caractere (text) în număr întreg (valoare de tip int).
Exemplul este doar ilustrativ, nu asigura functionalitatea completa pentru rezolvarea
problemei propuse.
int sir_la_intreg (char sir[ ])
{ int i, val_int, rez = 0;
for(i = 0; sir[i] >= ‘0’ && sir[i] <= ‘9’; i++)
{ val_int = sir[i] – ‘0’;
rez = rez*10 + val_int;
}
return rez;
}
void main( )
{ printf(“%d\n”, sir_la_intreg(“245”));
printf(“%d\n”, sir_la_intreg(“100”) + 25);
printf(“%d\n”, sir_la_intreg(“13*5”));
nu este cifră!!!
}
Datorita modului in care a fost conceputa functia de conversie (se iese din ciclul for
daca se gaseste un caracter care nu este cifra) pe ecran apar urmatoarele rezultate:

245
125
13 Demonstratie: 9_155.C

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 155
Funcţii de bibliotecă ce realizează conversii, descrise in stdlib.h:

atoi() sir car. in int strtod() sir car. in double


atof() sir car. in double strtol() sir car. in long int
atol() sir car. in long int strtoul() sir car. in unsigned long int

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 155
Macro-definiţii de bibliotecă (notiunea va fi explicata intr-un capitol urmator), descrise
in ctype.h, ce testează categoria din care face parte un anumit caracter (litera, cifra,
caracter de punctuatie etc.) sau transforma valoarea caracterului:

Rezultatul este 1 daca variabila c indeplineste conditia (si 0 in caz


contrar):
isalnum(c) literă sau cifră
isalpha(c) literă
isdigit(c) cifră
iscntrl(c) caracter de ştergere sau un control obisnuit
isascii(c) caracter ASCII valid
isprint(c) caracter tipăribil
isgraph(c) caracter tipăribil (excepţie spaţiu)
islower(c) literă mică
isupper(c) literă mare
ispunct(c) caracter de punctuaţie
isspace(c) spaţiu, tab, CR(carriage return), LF(line feed), tab vertical, FF
(form feed)
isxdigit(c) cifră hexazecimală: ‘0’…’9’,’ A’…’F’
Converteşte caracterul c
toupper(c) [‘a’…’z’] -> [‘A’ …’Z’]
tolower(c) [‘A’… ‘Z’] -> [‘a’…’z’]
toascii(c) > 127 la domeniul [0 – 127], stergand toti bitii cu exceptia celor 7
biti mai puţin semnificativi

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 156
9.3 Operaţii cu şiruri de caractere

 Afişarea şirurilor de caractere prin funcţii standard


 Citirea şirurilor de caractere de la tastatură
 Funcţii de bibliotecă pentru operaţii cu şiruri de
caractere descrise în fisierul standard string.h
 Tablouri cu elemente de tip pointer – Particularizare
 Argumente în linia de comandă

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 156
9.3.1 Afişarea şirurilor de caractere prin functii standard

char cuvant[25]=”Demonstratie”;
adresa de început a şirului de caractere ce trebuie afişat
 printf(”%s\n”, cuvant ); /*apelarea funcţiei*/

specificator de format pentru afişarea unui şir de caractere terminat


cu ‘\0’

 int puts(char * cuvant); /*prototipul funcţiei*/

adresa de început a şirului de caractere ce trebuie afişat


indicator de eroare 0 afişare corect finalizată
≠0 eroare
 funcţia afişează cuvant pe o linie a ecranului şi poziţionează cursorul la
începutul liniei următoare
 nu necesită specificarea unui format de afişare
 este specializată doar în afişarea şirurilor de caractere
 este mai rapidă şi ocupă mai puţină memorie decât printf()

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 157
9.3.2 Citirea şirurilor de caractere de la tastatură

Funcţia de bibliotecă scanf()


char linie[80];
scanf(“%s”, linie); /*numele tabloului este chiar adresa zonei de memorie asociate,
deci nu este necesar operatorul &*/

 Citeşte de la tastatură toate caracterele numai până când intâlneşte un caracter


spaţiu, Tab sau sfârşit de linie. La sfârşitul tabloului astfel citit pune caracterul nul.
Ex: dacă se introduce de la tastatură testare funcţionare ENTER , în tabloul de
caractere numit linie se va înscrie doar şirul testare (cele 7 litere plus caracterul ‘\0’).

 Caracteristica menţionată anterior recomandă funcţia scanf() pentru citirea textelor


“cuvânt cu cuvânt”.

 Dimensionarea tabloului de caractere, la declarare, trebuie făcută cu multă atenţie.


Ex:
char cuvant[5];
scanf(“%s”, cuvant);
/*dacă se tastează “testare”, rezultatul este imprevizibil (se încearcă înscrierea a
8 caractere într-un tablou cu maximum 5 elemente)*/

Demonstratie: 9_157.C

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 157
Funcţia de bibliotecă gets()

char* gets(char *sir); /*prototipul funcţiei*/

numele tabloului (sau adresa de început a zonei de memorie) în


care se va memora şirul de caractere citit
adresa tabloului primit ca parametru

 Citeşte un şir de caractere de la tastatură şi îl pune la adresa specificată ca


parametru
 Specific: citeşte toate caracterele tastate doar până când întâlneşte caracterul
linie nouă sau sfârşit de fişier. Adaugă apoi caracterul ‘\0’ la sfârşitul
tabloului astfel citit
 Această caracteristică recomandă funcţia gets() pentru citirea textelor „linie
cu linie”.

Demonstratie: 9_158.C

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 158
9.3.3 Funcţii de bibliotecă pentru operaţii cu şiruri de
caractere descrise în fisierul standard string.h
Operaţii:
 determinarea lungimii unui şir de caractere;
 copierea şi concatenarea şirurilor;
 compararea şirurilor din punct de vedere lexicografic;
 căutarea unor caractere în şir;
 convertirea (transformarea) caracterelor din şir

OBS.
 O parte dintre exemplele ce vor fi prezentate in aceasta sectiune au fost
preluate si adaptate din volumul “Teach Yourself C in 21 Days” - Bradley L.
Jones, Peter Aitken. Este vorba despre exemplele de utilizare a functiilor de
biblioteca.

 Continutul explicit al sectiunii este prezentat in slide-urile ce cuprind paginile


159-169
 Pentru ultimul exemplu, descris la finalul acestei sectiuni, se face demonstratie
“live” la ora de curs (varianta corecta si varianta incorecta)

Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 158

S-ar putea să vă placă și