InfoBook.ro ← Harta anului
Modul 05 · Șiruri de caractere
Modul 05 · Conținuturi 1.2 + 3.2 · esențial BAC

Literele devin numere: char & șiruri

Până acum am lucrat cu tipuri numerice — int, long long, float. Tehnologia a avut însă nevoie și de litere: așa s-a născut tipul char. Iar un șir de caractere? E doar un vector de char-uri — exact ce știi de la vectori (clasa a IX-a).

🎯 Obiectiv 1Înțelegi tipul char și tabelul ASCII — și faci aritmetică cu litere.
🎯 Obiectiv 2Declari, citești (cin vs getline) și parcurgi șiruri de caractere C-style.
🎯 Obiectiv 3Stăpânești funcțiile cstring: strlen, strcpy, strcat, strcmp, strchr, strstr, strtok.
1

Tipul char și tabelul ASCII

Un char stochează un număr de la 0 la 127 — iar fiecărui număr îi corespunde un simbol. Calculatorul nu știe litere: știe doar coduri.

🔡 Explorator ASCII — scrie un caracter sau un cod

caracter
T
cod ASCII
84
'A' = 65 'Z' = 90 'a' = 97 'z' = 122 '0' = 48 '9' = 57 spațiu = 32
Cele 3 ancore de reținut: 'A' = 65, 'a' = 97, '0' = 48. Literele mari, literele mici și cifrele sunt consecutive — pe asta se bazează toate trucurile care urmează.

🧮 Aritmetica pe caractere — trucurile de aur ale BAC-ului

1char c = 'A';
2cout << c + 1; // 66 (număr!)
3cout << (char)(c + 1); // 'B'
4char d = '7';
5int val = d - '0'; // 7 — cifra reală!
1// mică → MARE: scazi distanța 'a'-'A' = 32
2c = c - 'a' + 'A';
3// MARE → mică: invers
4c = c - 'A' + 'a';
5// e literă mică? 'a' <= c && c <= 'z'
testează:
2

Șirul de caractere = vector de char + terminator

Declari un vector de char-uri, iar C++ marchează sfârșitul textului cu un caracter invizibil: '\0' (codul 0).

📦 Anatomia unui șir în memorie — scrie orice cuvânt

char cuvant[15] =
De ce contează '\0': el spune funcțiilor unde se termină textul. strlen numără caracterele PÂNĂ la '\0' (fără el!). De-asta la char v[15] încap doar 14 caractere utile — unul e mereu rezervat terminatorului.

Citirea: cin se oprește la spațiu, getline ia tot rândul

cin >> cuvant;

1char cuvant[15];
2cin >> cuvant;
3cout << cuvant;

Regulile lui cin: sare caracterele albe de la început, citește de la primul caracter ne-alb și se oprește la primul spațiu.

cin.getline(s, nr);

1char s[101];
2cin.getline(s, 101);
3cout << s;

Citește maxim nr−1 caractere (locul lui '\0'!) și se oprește la '\n' (Enter) — deci ia tot rândul, cu spații cu tot.

tastatură:

Parcurgerea — exact ca la vectori

1char s[101]; cin >> s;
2int n = strlen(s); // lungimea (necesită <cstring>)
3for (int i = 0; i < n; i++)
4 cout << s[i] << ' '; // s[i] = un char, ca v[i]!
Capcană de viteză: nu scrie i < strlen(s) direct în for — strlen s-ar recalcula la FIECARE pas. Salvează lungimea o dată în n, apoi compară cu n.
3

Funcțiile din <cstring>

Trusa completă pentru șiruri C-style. Observație importantă: aceste funcții primesc de fapt un pointer către începutul șirului — de aceea merge magia cu s+i.

strlen(s) — STRing LENgth

Returnează lungimea (fără '\0').

char s[128] = "ana";
strlen(s) // 3
🎯 Problema Vocale ↗
cum e scrisă de la zero
1unsigned int strlen(char s[]) {
2 unsigned int i = 0;
3 for (i = 0; s[i] != NULL; i++);
4 return i;
5}

strcpy(dest, sursa) — STRing CoPY

Copiază sursa în destinație — echivalentul lui x = y (care NU merge pe șiruri!). strncpy copiază doar primele n caractere.

char s[128] = "mere";
strcpy(s, "pere"); // s = "pere"
🎯 Problema LungimeMaxima ↗
cum e scrisă de la zero
1void strcpy(char destinatie[], char sursa[]) {
2 unsigned int i = 0;
3 for (i = 0; sursa[i] != NULL; i++)
4 destinatie[i] = sursa[i];
5 destinatie[i] = '\0';
6}

strcat(dest, sursa) — conCATenate

Lipește sursa la sfârșitul destinației. strncat lipește doar primele n caractere.

char s[128] = "merele sunt ";
strcat(s, "sanatoase");
// "merele sunt sanatoase"
🎯 Problema InsertInvers ↗
cum e scrisă de la zero
1void strcat(char destinatie[], char sursa[]) {
2 unsigned int i = 0, j = 0;
3 for (i = 0; destinatie[i] != NULL; i++); // i ajunge la final
4 for (j = 0; sursa[j] != NULL; j++, i++)
5 destinatie[i] = sursa[j]; // concatenarea
6 destinatie[i] = '\0'; // terminatorul!
7}

strcmp(s1, s2) — CoMPare

< 0 dacă s1 vine înaintea lui s2 (alfabetic/lexicografic), 0 dacă sunt identice, > 0 altfel. strncmp compară doar primele n.

strcmp("mere", "mere") // 0
strcmp("mere", "pere") // < 0
🎯 Problema minim lexicografic ↗
cum e scrisă de la zero
1int strcmp(char s1[], char s2[]) {
2 unsigned int i = 0;
3 for (i = 0; s1[i] != NULL && s2[i] != NULL && s1[i] == s2[i]; i++);
4 if (s1[i] == NULL && s2[i] == NULL)
5 return 0;
6 else
7 return s1[i] - s2[i];
8}

strchr(s, c) — CHaRacter

Pointer către PRIMA apariție a caracterului c — adică sufixul care începe acolo. NULL dacă nu există.

char s[] = "Calul sare azi";
strchr(s, 'u') // "ul sare azi"
🎯 Problema Caractere ↗
cum e scrisă de la zero
1char* strchr(char sir[], char caracter) {
2 for (unsigned i = 0; sir[i] != NULL; i++)
3 if (sir[i] == caracter)
4 return sir + i;
5 return NULL;
6}

strstr(s, sub) — STRing STRing

Pointer către prima apariție a subșirului — sufixul de la acea poziție. NULL dacă nu există.

strstr(s, "sare") // "sare azi"
poziția: strstr(s,"sare") - s // 6
🎯 Problema PbInfo ↗
cum e scrisă de la zero
1char* strstr(char sir[], char subSir[]) {
2 for (unsigned i = 0; sir[i] != NULL; i++)
3 if (sir[i] == subSir[0]) {
4 int gasit = 1, k = i + 1;
5 for (unsigned j = 1; subSir[j] != NULL; j++) {
6 if (sir[k] != subSir[j]) { gasit = 0; break; }
7 k++;
8 }
9 if (gasit == 1) return sir + i;
10 }
11 return NULL;
12}

strtok(s, sep) — TOKen · ⭐ cea mai întâlnită la BAC!

„Sparge" șirul în bucăți (token-uri) după separatori. Primul apel primește șirul; apelurile următoare primesc NULL. Perfect pentru cuvintele unei propoziții.

1char s[128] = "Calul sare azi";
2char *cuvant = strtok(s, " ");
3while (cuvant != NULL) {
4 cout << "token: " << cuvant << '\n';
5 cuvant = strtok(NULL, " "); // următorul!
6}

⚗ Laborator cstring — testează orice funcție

s1 = s2 =
alege o funcție 👆

🪄 Trucul suprem: strcpy(s + i, s + j) — foarfeca de șiruri

Pentru că funcțiile primesc pointeri, s + i înseamnă „șirul care începe la poziția i". Copiind peste el șirul de la poziția j, elimini caracterele dintre i și j. Așa se șterge un caracter la BAC!

s = i = j =
Șablonul de eliminare a unui caracter: strcpy(s + i, s + i + 1); — șterge caracterul de la poziția i. Apare în nenumărate subiecte de BAC (elimină toate vocalele, elimină duplicatele…).

Exemplu complet cu <cstring>: numără vocalele + cenzurează un cuvânt

# numărarea vocalelor — cu strchr

1char s[101]; cin.getline(s, 101);
2char voc[] = "aeiouAEIOU";
3int vocale = 0;
4for (int i = 0; s[i] != 0; i++)
5 if (strchr(voc, s[i])) // s[i] e vocală?
6 vocale++;

# cenzurarea unui cuvânt — cu strstr

1int L = strlen(cuv);
2char *poz = strstr(text, cuv); // caută subșirul
3while (poz != NULL) {
4 for (int k = 0; k < L; k++)
5 poz[k] = '*'; // suprascriu cu *
6 poz = strstr(poz + 1, cuv); // următoarea apariție
7}
Cum lucrează funcțiile: strchr(voc, c) întoarce un pointer ≠ NULL dacă litera c apare în șirul voc — perfect pentru „e vocală?". strstr(text, cuv) caută un CUVÂNT întreg (subșir) și dă adresa lui; de acolo suprascrii literele cu '*'. Ambele sunt din <cstring>.
char[] sau string? La BAC apar amândouă — subiectele clasice folosesc char[] + cstring (ca aici), dar string simplifică enorm codul propriu. Regula practică: citește enunțul și folosește ce ți se dă în semnătură.
4

Clasa string (C++) și funcțiile <cctype>

Alternativa modernă la char[]: clasa string cu metodele ei — plus testele și conversiile pe caractere individuale.

.length() / .size()

Numărul de caractere — identice.

string s = "Informatica";
s.length() // 11

.substr(pos, len)

Subșir de len caractere de la poziția pos (0-indexat). Fără len: tot restul.

s.substr(0, 4) // "Info"
s.substr(5) // "matica"

.find(what) → npos

Poziția primei apariții — sau string::npos dacă nu există.

string s = "abcdefabc";
s.find("cd") // 2
s.find("abc", 1) // 6

.erase · .insert · .replace

Șterge len de la pos · inserează la pos · înlocuiește len caractere cu alt text.

s.erase(5, 5); s.insert(5, " mare");
s.replace(6, 4, "mic");

concatenare: + și +=

+ creează un string nou; += modifică direct. La string, „=" CHIAR funcționează — spre deosebire de char[]!

string c = a + b;
a += b; a += '!';

to_string(n) · stoi(s)

Număr → string · string → int. Trucul s[i] - '0' merge și aici.

to_string(42).length() // 2
stoi("123") + 1 // 124

<cctype> — teste pe caractere

isdigit, isalpha, isalnum, isupper, islower, isspace — nenul = adevărat.

if (isdigit('7')) // DA
if (isalpha('A')) // DA

<cctype> — conversii

toupper / tolower — dacă nu e literă, îl lasă neschimbat.

(char)toupper('a') // 'A'
for (int i = 0; i < s.size(); i++)
s[i] = toupper(s[i]);

Exemplu complet: numărarea vocalelor + cenzurarea unui cuvânt

1string s; getline(cin, s);
2int vocale = 0;
3string voc = "aeiouAEIOU";
4for (int i = 0; i < s.size(); i++)
5 if (voc.find(s[i]) != string::npos)
6 vocale++;
1string stars(cuv.size(), '*');
2int poz = text.find(cuv);
3while (poz != string::npos) {
4 text.replace(poz, cuv.size(), stars);
5 poz = text.find(cuv, poz + 1);
6}
char[] sau string? La BAC apar amândouă — subiectele clasice folosesc char[] + cstring, dar string simplifică enorm codul propriu. Regula practică: citește enunțul și folosește ce ți se dă în semnătură.
5

Exerciții — direct de pe pbInfo

Problemele clasice de șiruri, exact tipul care pică la BAC și la olimpiadă. Fiecare aplică o funcție din lecție.

strlen · strchr

Vocale

Numără vocalele dintr-un text. 🎯 pbinfo/11 ↗

strcmp

Minim lexicografic

Cel mai „mic" cuvânt alfabetic dintr-o listă. 🎯 pbinfo/2118 ↗

strcpy · foarfeca

InsertInvers

Inserări și mutări de caractere într-un șir. 🎯 pbinfo/2584 ↗

strstr

Caută subșir

Poziția unui cuvânt într-un text. 🎯 pbinfo/1346 ↗

strtok ⭐

Cuvinte9

Prelucrează cuvintele unei propoziții. 🎯 pbinfo/2797 ↗

strtok · frecvențe

nrA

Câte cuvinte încep cu litera A. 🎯 pbinfo/810 ↗

Sfat de examen: aproape orice cerință de șiruri se reduce la o parcurgere for (i=0; s[i]; i++) plus una–două funcții din <cstring>. Identifică întâi „ce trebuie găsit/numărat/șters" și alege funcția potrivită.
6

Test grilă — nivel BAC

Întrebări cu cod, exact în stilul subiectelor. Alege un răspuns la fiecare — vezi imediat explicația.

Fișa de recapitulare

Ce trebuie să reții din acest modul.

char = număr. 'A'=65, 'a'=97, '0'=48 — mari, mici și cifre sunt consecutive. c-'0' = cifra reală.
șir = vector de char + '\0'. La char v[15] încap 14 caractere utile; strlen numără până la '\0'.
cin vs getline. cin>>s se oprește la spațiu; cin.getline(s,n) ia tot rândul.
<cstring>: strlen, strcpy, strcat, strcmp, strchr, strstr, strtok. Primesc pointeri → merge magia s+i.
Foarfeca. strcpy(s+i, s+i+1) șterge caracterul de la poziția i — șablonul „elimină vocalele/duplicatele".
strtok ⭐. Primul apel: șirul; următoarele: NULL. Cel mai des întâlnit la BAC pentru cuvintele unei propoziții.
← anteriorModul 04 · Pointeri următor →Modul 06 · Matrice de caractere