PROGRAMARE IN LIMBAJUL C –
CURSUL 7
ŞIRURI DE CARACTERE
LECT. UNIV. TÎRŞU VALENTINA
1
Şirurile in C
■ Sirurile in C sunt simple tablouri de caractere:
– Exemplu: char s [10];
■ Sirul s este un tablou de 10 caractere.
■ Sfârşitul unui şir de caractere este marcat cu caracterul
null, care se reprezintă prin secvenţa escape \0.
■ De exemplu:
char str [10] = {‘1', ‘2', ‘3', ‘4', '\0'};
■ Caracterul null determina lungimea sirului.
■ De exemplu, putem declara şi defini un tablou de
caractere şi să-l iniţializăm cu un şir de caractere
constant:
char string[] = "Hello, world!";
2
Accesarea individuală a caracterelor
■ Primul element al oricarui tablou in C are indexul 0. Al doilea element
are indexul 1, s.a.m.d. ...
char s[10];
s[0] = 'h'; h i ! \0 ? ? ? ? ? ?
s[1] = 'i’;
s[2] = '!'; s [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
s[3] = '\0';
■ Aceste notatii pot fi utilizate in toate instructiunile si expresiile din
limbajul C:
■ Totuşi compilatorul C/C++ nu adaugă automat terminatorul NULL, decât
în cazul folosirii funcţiilor predefinite fgets() şi gets() (functii de citire din
fisiere sau de la tastatura), iar în celelalte cazuri este necesar ca
programatorul să adauge terminatorul de şir.
int main() {
char sir[256];
int i;
for(i=0; i<26;i++) sir[i]=‘A’+I;
sir[i]=‘\0’;
cout<<"Sirul de caractere contine: "<<sir;
return 0;}
3
Funcţii specifice şirurilor de caractere
În biblioteca limbajului C/C++ există câteva funcţii specifice
şirurilor de caractere:
■ în fişierul standard de intrare / ieşire – stdio.h, avem funcţiile
getchar(), gets() şi puts().
■ în fişierul string.h, avem mai multe funcţii specifice prelucrării
șirurilor, funcții care vor fi prezentate în continuare.
■ Pentru citirea sirurilor de caractere care contin spatii se poate
folosi metoda getline a funcției cin:
[Link](variabila_sir, dimensiune_maxima);
Exemplu:
char variabila_sir[120];
[Link](variabila_sir, 120)
4
Funcţii pentru operaţii cu şiruri de caractere (1)
Functiile pentru operatii cu siruri se gasesc in header-ul <string.h>.
■ Funcţia strlen – returnează lungimea efectiva a unui sir (fără a
număra terminatorul de sir).
sintaxa - int strlen(nume_sir);
Exemplu: char a[50]=”ora de informatica”; // strlen(a) = 18
■ Funcţia strcpy – copie şirul sir_sursa in sir_destinaţie
sintaxa – char* strcpy(sir_destinatie,sir_sursa);
Exemplu: char a[50]=”primul sir”,
b[40]=”al doilea sir”;
a=b; //eroare
strcpy(a,b); // a = ”al doilea sir”; b=”al doilea sir”;
5
Funcţii pentru operaţii cu
şiruri de caractere (2)
■ Funcţia strcat – adaugă la şirul dest şirul sursa. Şirul sursa rămâne
nemodificat. Operaţia se numeşte concatenare si nu este comutativa.
sintaxa – char* strcat(dest,sursa);
Exemplu: char a[20]=”vine ”,b[20]=”vacanta?”;
strcat(a,b); // a = ”vine vacanta?”;
■ Funcţia strncat – adaugă la dest primele nr caractere din şirul sursa.
Şirul sursa rămâne nemodificat.
sintaxa – char* strncat(dest,sursa,nr);
Exemplu: char a[20]=”este un ”;
char b[20]=”programare?”;
strncat(a,b,7); // a = ”este un program”;
6
Funcţii pentru operaţii cu
şiruri de caractere (3)
■ Funcţia strchr – returneaza o valoare pozitiva daca un caracter apare intr-un sir, 0 in caz
contrar.
sintaxa – char* strchr(sir,c);
Exemplu: char a[25]="acesta este un sir", b='t', c='x', *d;
cout<<"\n"<<strchr(a,b); // se tipareste ”ta este un sir”;
cout<<"\n"<<strchr(a,c); /* nu se tipareste nimic (se tipareste 0 daca se face o
conversie la int a lui strchr(a,c) ;*/
■ Funcţia strstr – returneaza o valoare pozitiva daca un sir apare intr-un alt sir, 0 in caz
contrar.
sintaxa – char* strstr(sir1, sir2);
Exemplu: char sir1[]= "primul sir", sir2[]="sir";
if (strstr(sir1,sir2)) cout <<"Am gasit subsirul!"
7
Funcţii pentru operaţii cu şiruri
de caractere (4)
■ Funcţia strcmp – are rolul de a compara doua siruri de
caractere. Valoarea returnata este diferenta dintre codurile
ASCII ale primelor caractere care nu coincide. Funcţia strcmp
face distinctie intre literele mari si cele mici ale alfabetului
sintaxa - int strcmp(sir1, sir2);
Exemplu: cout << strcmp("carte", "carte"); //0
8
Funcţii pentru operaţii cu şiruri
de caractere (5)
■ Programul C pentru a copia un şir de caractere într-altul:
#include <iostream>
#include <string.h> /* contine declaratii de functii pentru manipularea sirurilor */
using namespace std;
int main()
{
char string1[] = "Hello, world!";
char string2[20];
cout<<string1;
strcpy(string2, string1);
cout<<"\n"<<string2;
return 0;
}
■ Exemplu pentru compararea a doua siruri de caractere:
char string3[] = "acesta este ";
char string4[] = "un test";
if(strcmp(string3, string4) == 0)
cout<<“\n sirurile de caractere sunt egale\n";
else cout<<"sirurile de caractere sunt diferite\n";
9
Ffuncţiile de conversie dintr-un șir de caractere
în număr (1)
■ În fişierul <stdlib.h> există câteva funcţii care prelucrează
şirurile de caractere.
10
Ffuncţiile de conversie dintr-un șir de
caractere în număr (2)
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int numar_int;
float numar_real;
long numar;
numar_int = atoi("6789");
numar_real = atof("12.345");
numar = atol("1234567890L");
cout<<numar_int<<" "<<numar_real<<" "<<numar;
return 0;
}
11
Funcţiile de conversie dintr-un număr într-un
şir de caractere
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int numar_int = 6789;
long numar = 1234567890L;
char sir[25];
itoa(numar_int, sir, 10);
cout<<" numar = "<< numar_int<<" sir = "<<sir;
ltoa(numar, sir, 10);
cout<<" numar = "<< numar<<" sir = "<<sir;
return 0;
}
12
Definiții de funcții
13
Funcţia strlen
■ Iată o versiune a funcţiei strlen:
int mystrlen(char str[])
{
int i;
for(i = 0; str[i] != '\0'; i++)
{}
return i;
}
■ În acest caz, tot ce trebuie să facem este să găsim terminatorul şirului
(caracterul null)
■ E suficient să scriem o instrucţiune for al cărei corp nu conţine nici o
instrucţiune
■ Pentru a obţine acelaşi efect am fi putut folosi şi instrucţiunea vidă care
se constituie doar din caracterul punct şi virgulă:
for(i = 0; str[i] != '\0'; i++)
;
14
Functia strcpy (2)
■ Iată o versiune a funcţiei strcpy:
mystrcpy(char dest[], char src[])
{
int i = 0;
while(src[i] != '\0')
{
dest[i] = src[i];
i++;
}
dest[i] = '\0';
}
■ Funcţia am denumit-o mystrcpy şi nu strcpy pentru ca numele ei să nu intre în conflict cu
versiunea din biblioteca standard C.
■ Funcţia operează destul de simplu: se parcurge pe rând fiecare caracter din şirul src şi cât
timp este diferit de \0 acestea sunt stocate, unul câte unul, în poziţia corespunzătoare din
şirul de caractere dest.
■ Când termină de parcurs şirul src, şirului dest i se adaugă şi terminatorul \0. (După ce se
iese din bucla while, i va avea o valoare cu 1 mai mare decât indicele ultimului caracter din
şirul src).
15
Funcţia strcmp
■ Iată o versiune a funcţiei strcmp:
mystrcmp(char str1[], char str2[])
{
int i = 0;
while(1)
{
if(str1[i] != str2[i])
return str1[i] - str2[i];
if(str1[i] == '\0' && str2[i] == '\0')
return 0;
i++;
}
}
■ Caracterele sunt comparate unul câte unul. Dacă, caracterele de pe o poziţie
diferă înseamnă că şirurile sunt diferite şi trebuie să returnăm o valoare mai
mică decât zero dacă primul şir de caractere (str1) este mai mic, în ordine
alfabetică decât al doilea.
16
Exemplu
■ Programul de mai jos calculează consumul de combustibil al unui autoturism:
#include <stdio.h>
#include <stdlib.h> /* pentru atoi() */
int getline(char [], int);
int main()
{
char inputline[100];
float km,litri,kpl;
printf("introduceti distanta parcursa:\n");
getline(inputline, 100);
km = atoi(inputline);
printf("introduceti catitatea de benzină folosita:\n");
getline(inputline, 100);
litri = atoi(inputline);
kpl = km / litri;
printf("ati facut %.2f kilometrii cu 1 litru\n", kpl);
return 0;
}
17
Probleme cu șiruri de caracatere
■ Problema 1:
Enunţ: Să se afişeze numărul de vocale dintr-un text scris cu litere
mici, memorat intr-o variabilă de tip șir de caractere.
Exemplu:
Date de intrare: Programarea calculatoarelor
Date de ieșire: Exista 12 vocale in text
21
Problema 1:
rezolvare
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char text[100];
char vocale[] = "aeiou";
int contor = 0;
cout<<"Introduceti text: ";
[Link](text, 100);
for (int i=0; i<strlen(text); i++)
for (int j=0; j<strlen(vocale); j++)
if (text[i] == vocale[j]) contor++;
cout<<"Exista "<<contor<<" vocale in text. ";
return 0;
}
22
Probleme cu șiruri de caracatere
■ Problema 2:
Enunţ: Să se afişeze cu litere mari un text dat, de maxim 255
caractere.
Exemplu:
Date de intrare text: liMBajUl c++
Date de ieşire LIMBAJUL C++
23
Problema 2:
rezolvare
#include <iostream>
using namespace std;
int main()
{
char sir[255];
cout<<"Introduceti textul: ";
[Link](sir, 255);
for (int i=0; sir[i]!=0; i++)
if (sir[i] >= 'a' && sir[i] <= 'z') sir[i] = sir[i] - 'a' + 'A';
cout<<sir;
}
24
Probleme cu șiruri de caracatere
■ Problema 3:
Se citește un șir de caractere. Să se afișeze litera cea mai des
întâlnită.
Exemplu:
Date de intrare text: carte de informatica si programare
Date de ieşire: a apare de 5 ori
25
Problema 3:
rezolvare
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char sir[1000], carac_max, c;
int i, frecv[256], max=0; // frecv - vector de frecvente
cout<<"Dati sirul de caractere: ";
[Link](sir,1000);
for (i=0; i<256; i++) frecv[i] = 0;
for (i=0;i<strlen(sir);i++)
{
c=sir[i];
frecv[c]=frecv[c]+1;
if (frecv[c]>max){
max=frecv[c];
carac_max=c;
}
}
cout<<carac_max<<" apare de "<<max<<" ori";
}
26
Probleme propuse spre
rezolvate – șiruri de caractere
■ Să se afișeze toate prefixele și sufixele unui cuvânt citit de la
tastatură.
■ Exemplu: Date de intrare: informatica
■ Date de ieşire:
I a
In ca
Inf ica
Info tica
Infor atica
Inform matica
Informa rmatica
.. ..
27
Probleme propuse spre
rezolvate – șiruri de caractere
■ Se citește de la tastatură un caracter c și un text de maxim
100 de carectere. Afișați de câte ori apare caracterul c în
cadrul textului. Literele mari se vor considera diferite de
literele mici.
Exemplu:
Date de intrare: Acesta este un simplu exemplu Caracterul e
Date de ieşire: litera ‘e’ apare de 5 ori.
28
Probleme propuse spre
rezolvate – șiruri de caractere
■ Se citește de la tastatură un șir de maxim 100 de carectere
format numai din litere și cifre. Afișați numărul literelor mari,
numărul literelor mici și numărul caracterelor de tip cifră din
textul dat.
Exemplu:
Date de intrare: S-a nascut la Targu Jiu in 1968 pe 21 martie
Date de ieşire: Se gasesc 25 de litere mici, 2 litere mari si 6 cifre
29
30