Șiruri de Caractere în C++

Breviar teoretic & practic pentru clasa a 11-a

1. Definire, Citire și Afișare

Un șir de caractere în C++ este un tablou (vector) de tip char, care are o proprietate specială: ultimul caracter valid este urmat obligatoriu de caracterul nul ('\0'). Acesta marchează sfârșitul șirului în memorie.

Exemplu Definire:
char s[21]; // Maxim 20 caractere utile + terminatorul
char text[] = "info"; // Compilatorul pune automat '\0' la final

Metode de citire

1. Operatorul `cin >>`

Citește un singur cuvânt. Se oprește la primul spațiu alb (spațiu, tab, enter).

Exemplu cin:
char s[50];
cout << "Introdu un cuvant: ";
cin >> s; 
// Daca introduci "Ana are mere", s va retine doar "Ana"

2. Funcția `cin.get()`

Citește inclusiv spații, dar nu extrage caracterul `New Line` (Enter) din buffer, acesta rămânând pentru citirea următoare (ceea ce poate cauza probleme).

Exemplu cin.get():
char s[50];
cin.get(s, 50); 
cin.get(); // Este nevoie de un get() gol pentru a consuma Enter-ul ramas

3. Funcția `cin.getline()`

Este cea mai sigură metodă pentru a citi o propoziție. Citește toată linia până la Enter și elimină Enter-ul din buffer.

Exemplu cin.getline():
char s[100];
cout << "Introdu propozitia: ";
cin.getline(s, 100);
// Daca introduci "Ana are mere", s va retine tot textul.

Modalități de afișare

Afișarea șirurilor se face folosind cout. Deoarece numele șirului este un pointer către primul element, putem folosi aritmetica pointerilor pentru a afișa șirul începând de la o anumită poziție.

Exemplu 1 (Afișare normală):
char s[] = "informatica";
cout << s; 
// Afiseaza: informatica
Exemplu 2 (Afișare de la o poziție anume):
char s[] = "informatica";
cout << s + 2; 
// Sare peste primii 2 indici (0 si 1)
// Afiseaza: formatica

2. Funcții la nivel de caracter

Aceste funcții se găsesc în biblioteca <cctype>. Ele primesc un caracter și returnează o valoare nenulă (true) sau 0 (false).

isdigit(char c)

Verifică dacă caracterul este o cifră ('0' - '9').

Exemplu 1:
char c = '7';
if (isdigit(c)) cout << "Este cifra";
// Afiseaza: Este cifra
Exemplu 2:
char s[] = "Anul 2024";
int k = 0;
for(int i=0; s[i] != '\0'; i++) {
    if(isdigit(s[i])) k++;
}
cout << "Sunt " << k << " cifre"; 
// Afiseaza: Sunt 4 cifre

isalpha(char c)

Verifică dacă caracterul este o literă (mică sau mare).

Exemplu 1:
if (isalpha('A')) cout << "Este litera";
// Afiseaza: Este litera
Exemplu 2:
char cod[] = "AB12";
if (isalpha(cod[0]) && isalpha(cod[1])) 
    cout << "Primele doua sunt litere";
// Afiseaza: Primele doua sunt litere

isalnum(char c)

Verifică dacă este caracter alfanumeric (literă SAU cifră).

Exemplu 1:
if (isalnum('X')) cout << "Da";
// Afiseaza: Da
Exemplu 2:
// Verificam daca parola contine doar litere si cifre
bool ok = true;
char pass[] = "Pass_1";
for(int i=0; pass[i]; i++)
    if(!isalnum(pass[i])) ok = false;

if(!ok) cout << "Parola invalida";
// Afiseaza: Parola invalida (din cauza '_')

islower(char c) / isupper(char c)

Verifică dacă litera este mică, respectiv mare.

Exemplu 1:
if (islower('a')) cout << "Mica"; 
// Afiseaza: Mica
Exemplu 2:
char c = 'm';
if (islower(c)) c = toupper(c); // Devine 'M'
else if (isupper(c)) c = tolower(c);

cout << c;
// Afiseaza: M

3. Funcții pentru prelucrarea șirurilor

Bibliotecă necesară: <cstring>.

strlen(const char* s)

Returnează lungimea efectivă a șirului (fără terminator).

Exemplu 1:
cout << strlen("info"); // Afiseaza 4
Exemplu 2:
char s[] = "abcdef";
// Parcurgem pana la jumatate
for(int i=0; i < strlen(s)/2; i++) 
    cout << s[i]; // Afiseaza "abc"

strcpy(dest, sursa)

Copiază conținutul din sursă în destinație (inclusiv \0).

Exemplu 1:
char s[10];
strcpy(s, "test"); // s devine "test"
Exemplu 2:
char nume[20] = "Ion";
char nou[] = "Vasile";
strcpy(nume, nou); // nume devine "Vasile", "Ion" se pierde

strcat(dest, sursa)

Concatenează (adaugă) sursa la finalul destinației.

Exemplu 1:
char s[20] = "Ana ";
strcat(s, "are"); // s devine "Ana are"
Exemplu 2:
char prop[50] = ""; // Sir vid initial
strcat(prop, "Eu");
strcat(prop, " ");
strcat(prop, "invat."); 
// prop devine "Eu invat."

strchr(s, c)

Caută prima apariție a caracterului c în șirul s. Returnează un pointer la prima apariție sau NULL dacă nu există.

Exemplu 1:
char s[] = "banana";
if (strchr(s, 'n') != NULL) cout << "Gasit";
Exemplu 2:
char email[] = "elev@scoala.ro";
char *p = strchr(email, '@');
if(p) cout << p + 1; // Afiseaza "scoala.ro"

strstr(s, t)

Caută prima apariție a șirului t în șirul s. Returnează pointer sau NULL.

Exemplu 1:
char s[] = "invatam informatica";
if (strstr(s, "info")) cout << "Contine info";
Exemplu 2:
char text[] = "Ana are mere.";
char *p = strstr(text, "mere");
if(p) strncpy(p, "****", 4); 
// text devine "Ana are ****."

strncpy(dest, sursa, n)

Copiază exact n caractere. Atenție: Dacă sursa > n, nu pune terminatorul nul!

Exemplu 1:
char s[10];
strncpy(s, "inform", 4); 
s[4] = '\0'; // Obligatoriu manual!
cout << s; // "info"
Exemplu 2:
char s1[] = "rearanjare";
char s2[10];
// Copiem primele 2 litere ("re")
strncpy(s2, s1, 2);
s2[2] = '\0'; 

strncat(dest, sursa, n)

Adaugă primele n caractere din sursă la destinație. Adaugă automat terminatorul.

Exemplu 1:
char s[20] = "File";
strncat(s, ".cpp.bkp", 4); // s devine "File.cpp"
Exemplu 2:
char a[20] = "123";
char b[] = "456789";
// Adaugam doar 2 cifre din b
strncat(a, b, 2); // a devine "12345"

strtok(s, delimitatori)

Împarte șirul în cuvinte (token-uri). Modifică șirul inițial!

Exemplu 1:
char s[] = "azi,maine";
char *p = strtok(s, ","); // p pointeaza spre "azi"
Exemplu 2:
char text[] = "Ana are, mere.Pere?";
char *p = strtok(text, " ,.?"); // Primul apel cu sirul
while (p != NULL) {
    cout << p << endl;
    p = strtok(NULL, " ,.?"); // Urmatoarele cu NULL
}

4. Quiz Final

Analizează cu atenție secvențele de cod și răspunde.

1. Ce afișează secvența? char s[] = "info"; cout << strlen(s);
2. Ce afișează? char s[10] = "ab\0cd"; cout << strlen(s);
3. Ce index are ultimul 'b' în "abracadabra"?
4. Ce afișează codul? char s[]="ora"; s[0] = s[0] + 1; cout << s;
5. Ce va conține variabila `s`? char s[20]; strcpy(s, "mama"); strcpy(s, "tata");
6. Ce afișează secvența? if (strchr("AEIOUaeiou", 'A')) cout << "Vocala"; else cout << "Consoana";
7. Ce afișează? cout << isalpha('?');
8. Ce face `strcat(s, "x")`?
9. Ce afișează? char s[]="abc"; cout << s[3]; // Hint: caracterul invizibil
10. Completați funcția care verifică litere mari: `is_____`
11. Ce afișează? char s[]="bac"; if(strcmp(s, "abc") > 0) cout << "Mare"; else cout << "Mic";
12. Ce afișează? char s[20]="Ana "; strcat(s, "are"); cout << strlen(s);
13. Ce afișează? char s[] = "informatica"; cout << s + 2;
14. Ce afișează? char s[] = "12A"; if(isalnum(s[2])) cout << "OK";
15. Ce se întâmplă cu șirul sursă la `strtok`?
16. Ce afișează? char s[10]; strncpy(s, "abcde", 2); s[2]='\0'; cout << s;
17. Ce afișează? cout << (char)toupper('a');
18. Care funcție elimină caracterul Enter din buffer?
19. Ce afișează? char s[] = "test"; s[0] = 'v'; cout << s;
20. Ce afișează? char s[] = "AA"; cout << islower(s[0]);
21. Ce afișează? char s[]="info"; char t[]="info"; if(s == t) cout << "Egale"; else cout << "Diferite";
22. Ce afișează? char s[] = "1,2,3"; cout << strtok(s, ",");
23. Ce parametru folosim la apelurile succesive strtok?
24. Ce afișează secvența? char c = 'b'; if(strchr("AEIOUaeiou", c)) cout << "Vocala"; else cout << "Consoana";
25. Ce afișează? cout << strchr("banane", 'n');
26. Ce afișează? char s[] = "A+B"; cout << isalnum(s[1]);
27. Pentru a citi un șir care conține spații folosim:
28. Ce afișează? char s[] = "Info"; s[0] = '\0'; cout << strlen(s);
29. `strncpy` adaugă automat `\0` dacă lungimea maximă e atinsă?
30. Ce afișează? if (strstr("masina", "sin")) cout << "DA"; else cout << "NU";