Didaxis
lecție · Informatică

Caractere și șiruri

Un șir de caractere este o succesiune de caractere, de exemplu un cuvânt sau o propoziție. În C++, în stilul folosit la Bacalaureat, se memorează într-un tablou de tip char, iar după ultimul caracter util se află terminatorul, caracterul cu codul 0. Funcțiile din biblioteca cstring află lungimea, copiază, concatenează, compară și caută în șiruri.

Se face în:
Clasa a X-a
Clasa a XI-a
Actualizat la: 30 octombrie 2026
1pe scurtstratul 1 din 3 · rezumatul lecției

Pe scurt

Un caracter este o unitate de text, iar un șir este o succesiune de caractere. În C++, 'A' este un literal de tip caracter, în timp ce "A" este un literal șir. Textul "123" nu este numărul 123; nu îl poți aduna numeric fără conversie. În std::string s = "ana";, lungimea este 3 și indicii sunt 0, 1, 2.

Desen la lecția „Caractere și șiruri”
2în detaliustratul 2 din 3 · pentru clasă și Bacalaureat

În detaliu

Un caracter este o unitate de text, memorată în C++ într-o variabilă de tip char ca un cod întreg; un șir de caractere este o succesiune de caractere. Literalul 'A' (între apostrofuri) este un caracter, iar "A" (între ghilimele) este un șir de lungime 1. La Bac, șirul se memorează de obicei într-un tablou de char terminat cu '\0' (caracterul nul), care marchează sfârșitul textului: în char s[4] = "ana"; pozițiile 0, 1 și 2 conțin literele, iar poziția 3 conține terminatorul. Lungimea logică a textului este numărul de caractere dinaintea terminatorului, strlen(s), adică 3, iar dimensiunea tabloului este 4. Accesul la caracter se face prin indice, s[0], s[1], ..., numerotat de la 0. Textul "123" nu este numărul 123: pentru calcule se convertește.

Codul ASCII al unor caractere: '0' are 48, 'A' are 65, 'a' are 97. Cifrele sunt consecutive ('0' până la '9', cu codurile 48–57), la fel literele mari și literele mici; diferența dintre o literă mică și majuscula ei este 32. De aceea '7' - '0' este 7, 'a' + 2 este codul lui 'c', iar comparația 'b' < 'c' este adevărată. Funcția strlen(s) din <cstring> dă lungimea logică; strcmp(a, b) dă 0 pentru șiruri egale, o valoare negativă dacă a precede b în ordine lexicografică și una pozitivă altfel.

Exemplul 1 — lungime, cod, comparație.

#include <iostream>
#include <cstring>
using namespace std;
int main() {
    char s[4] = "ana", t[4] = "are";
    cout << strlen(s) << " " << (int)'A' << " " << (strcmp(s, t) < 0);
    return 0;
}

Se afișează 3 65 1: lungimea este 3, codul lui 'A' este 65, iar "ana" precede "are", pentru că primele litere coincid, iar 'n' < 'r'. Valoarea numerică exactă a rezultatului lui strcmp nu trebuie presupusă, doar semnul ei.

Exemplul 2 — lungimea logică și dimensiunea tabloului. Pentru char s[] = "abc"; compilatorul rezervă 4 octeți: trei pentru litere și unul pentru terminator. De aceea strlen(s) este 3, sizeof(s) este 4, iar s[3] are codul 0:

char s[] = "abc";
cout << strlen(s) << ' ' << sizeof(s) << ' ' << (int)s[3];

Secvența afișează 3 4 0. Dacă tabloul ar fi declarat char s[3] = "abc";, terminatorul nu ar încăpea, iar funcțiile care așteaptă terminatorul ar citi dincolo de tablou.

Memorarea și terminatorul. Caracterele utile ocupă pozițiile , iar pe poziția se află terminatorul '\0', după care funcțiile știu unde se termină șirul. De aceea tabloul are nevoie de un element în plus față de lungimea maximă din enunț: pentru cel mult 100 de caractere, char s[101];. Parcurgerea se face cu for (i = 0; s[i] != '\0'; i++) sau până la strlen(s), calculat o singură dată, înainte de buclă.

Caracterele sunt numere. Literele mici au coduri consecutive, de la 'a' (97) la 'z' (122), la fel cele mari și cifrele. De aici vin testele uzuale: s[i] >= 'a' && s[i] <= 'z' (literă mică), strchr("aeiou", s[i]) (vocală), s[i] - 'a' + 'A' (litera mare corespunzătoare), c - '0' (cifra din caracter) și '0' + cifra (caracterul din cifră). Funcțiile toupper și tolower din cctype fac aceleași transformări.

Funcțiile din cstring.

Ce În C++
Citirea unui cuvânt, a unei linii cin >> s;, cin.getline(s, 101);
Copierea lui t în s, adăugarea lui t la s strcpy(s, t);, strcat(s, t);
Prima apariție a unui caracter, a unui subșir strchr(s, 'a'), strstr(s, "re"): adresa găsită sau NULL
Împărțirea în cuvinte strtok(s, " "), apoi strtok(NULL, " ")

În strcpy și strcat, șirul s trebuie să aibă destul loc. strchr și strstr întorc adresa primei apariții; poziția ei se obține scăzând adresa de început: strchr(s, 'x') - s. strtok taie șirul în cuvinte după separatorii dați și îl modifică, punând terminatori în locul separatorilor.

Ștergerea și inserarea. Ca la orice tablou, ștergerea unui caracter mută spre stânga tot ce urmează, inclusiv terminatorul. Forma scurtă strcpy(s + i, s + i + 1) apare des în rezolvări, dar standardul limbajului nu garantează rezultatul când sursa și destinația se suprapun. O buclă care mută caracterele, ca în exemplul 4, sau memmove sunt sigure.

Clasa string. C++ are și clasa string, în care lungimea se află cu s.length(), concatenarea se face cu +, iar compararea cu == și <. Programa de examen descrie șirurile prin operații (citire, afișare, concatenare, căutare, extragere, inserare, eliminare, conversii), nu printr-o bibliotecă anume, iar baremul punctează orice rezolvare corectă. Exemplele de mai jos folosesc tablourile de char, cu care lucrează funcțiile din cstring. Un exemplu scurt cu string:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string a = "bac", b = "alaureat";
    string s = a + b;
    cout << s << " " << s.length() << " " << s.find("aur") << "\n";
    return 0;
}
bacalaureat 11 5

find întoarce poziția primei apariții, numărată de la 0: „aur” începe pe poziția 5.

Exemple suplimentare

Exemplul 3 — aritmetică cu caractere. Cifra '7' are valoarea numerică '7' - '0', adică 7. Litera următoare lui 'a' este (char)('a' + 1), adică 'b'. Din litera mare 'C' se obține litera mică corespunzătoare prin 'C' + ('a' - 'A'), adică 'c'. Pentru a testa dacă un caracter este literă mică se verifică c >= 'a' && c <= 'z'; pentru cifră, c >= '0' && c <= '9'.

Exemplul 4 — cifrele dintr-un șir. Se numără cifrele din textul "a1b23" și se adună valorile lor. Parcurgerea merge de la poziția 0 până la strlen(s) - 1, iar fiecare caracter este testat cu intervalul '0'..'9'.

char s[] = "a1b23";
int nr = 0, suma = 0;
for (int i = 0; i < strlen(s); i++)
    if (s[i] >= '0' && s[i] <= '9') {
        nr++;
        suma += s[i] - '0';
    }

Urmărirea: pentru caracterul 'a' nu este cifră; pentru , '1' este cifră, deci și ; pentru , 'b' este ignorat; pentru , '2' dă și ; pentru , '3' dă și . Dacă s-ar aduna direct s[i], fără scăderea lui '0', s-ar aduna codurile 49, 50 și 51, adică 150, nu cifrele 1, 2 și 3. Testul pe interval este corect pentru cifre, deoarece codurile lor sunt consecutive.

Cazul-limită este șirul vid: char s[] = ""; are lungimea logică 0 și dimensiunea tabloului 1, deoarece conține doar terminatorul, iar bucla de mai sus nu execută niciun pas pentru el.

Exemple rezolvate

Exemplul 1: numărul de vocale dintr-un text. Se citește un text cu cel mult 100 de caractere, litere mici și spații. Afișează numărul de vocale. Pentru „ana are mere” răspunsul este 6.

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[101];
    cin.getline(s, 101);
    int nr = 0, L = strlen(s);
    for (int i = 0; i < L; i++)
        if (strchr("aeiou", s[i]) != NULL)
            nr++;
    cout << nr << "\n";
    return 0;
}

Pentru intrarea ana are mere, programul afișează:

6

Spațiul nu se află în șirul "aeiou", deci nu este numărat. Atenție: strchr găsește și terminatorul, așa că bucla nu trebuie să ajungă la poziția .

Exemplul 2: inițiala fiecărui cuvânt, cu literă mare. Transformă în literă mare prima literă a fiecărui cuvânt. „bacalaureat la informatica” devine „Bacalaureat La Informatica”.

  1. Un caracter începe un cuvânt dacă este literă și este primul din șir sau se află după un spațiu.
  2. Litera mare se obține cu s[i] - 'a' + 'A'.
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[101];
    cin.getline(s, 101);
    for (int i = 0; s[i] != '\0'; i++)
        if (s[i] >= 'a' && s[i] <= 'z' && (i == 0 || s[i - 1] == ' '))
            s[i] = s[i] - 'a' + 'A';
    cout << s << "\n";
    return 0;
}

Pentru intrarea bacalaureat la informatica, programul afișează:

Bacalaureat La Informatica

Exemplul 3: cel mai lung cuvânt, cu strtok. Afișează cel mai lung cuvânt dintr-un text, iar la lungimi egale pe primul. Pentru „ziua de azi este frumoasa”, răspunsul este „frumoasa”.

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[101], best[101] = "";
    cin.getline(s, 101);
    char *p = strtok(s, " ");
    while (p != NULL) {
        if (strlen(p) > strlen(best))
            strcpy(best, p);
        p = strtok(NULL, " ");
    }
    cout << best << "\n";
    return 0;
}

Pentru intrarea ziua de azi este frumoasa, programul afișează:

frumoasa

Exemplul 4: ștergerea vocalelor. Șterge toate vocalele dintr-un cuvânt. „informatica” devine „nfrmtc”.

  1. Când găsești o vocală pe poziția , muți spre stânga, cu o poziție, toate caracterele de după ea, inclusiv terminatorul.
  2. După ștergere nu treci la poziția următoare: pe poziția a ajuns un caracter nou, care trebuie verificat și el (de exemplu, două vocale consecutive).
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[101];
    cin >> s;
    int i = 0;
    while (s[i] != '\0')
        if (strchr("aeiou", s[i]) != NULL) {
            for (int j = i; s[j] != '\0'; j++)
                s[j] = s[j + 1];        // muta si terminatorul
        } else
            i++;
    cout << s << "\n";
    return 0;
}

Pentru intrarea informatica, programul afișează:

nfrmtc

Pentru aeroport afișează rprt: cele două vocale de la început sunt șterse una după alta, pentru că nu avansează după ștergere.

Exemplul 5: nivel de examen, cuvinte cu aceeași literă la capete. Se citește un text cu cel mult 100 de caractere, cuvinte formate din litere mici, separate prin câte un spațiu. Afișează, separate prin câte un spațiu, cuvintele care încep și se termină cu aceeași literă, sau mesajul nu exista.

  1. strtok dă, pe rând, fiecare cuvânt p. Prima literă este p[0], ultima p[strlen(p) - 1].
  2. Un cuvânt de o literă respectă condiția (prima și ultima literă coincid).
  3. Pentru „ana are o casa cu cerdac”, cuvintele cerute sunt „ana”, „o” și „cerdac”.
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[101];
    cin.getline(s, 101);
    int gasit = 0;
    char *p = strtok(s, " ");
    while (p != NULL) {
        if (p[0] == p[strlen(p) - 1]) {
            if (gasit == 1)
                cout << " ";
            cout << p;
            gasit = 1;
        }
        p = strtok(NULL, " ");
    }
    if (gasit == 0)
        cout << "nu exista";
    cout << "\n";
    return 0;
}

Pentru intrarea ana are o casa cu cerdac, programul afișează:

ana o cerdac

Pentru bac la info afișează nu exista.

3pentru admiterestratul 3 din 3 · pentru examene

Pentru admitere

La urmărirea codului, diferențiază lungimea logică a textului de dimensiunea tabloului care îl stochează. Pentru char s[4] = "ana";, trei poziții țin literele și a patra terminatorul nul. Compararea textelor C nu se face cu == între tablouri: acesta compară adresele, nu conținutul. Pentru comparație folosește strcmp. strlen("ana") este 3, deși tabloul necesită 4 poziții. Expresia '7' - '0' transformă caracterul cifră în valoarea lui numerică. Dacă fragmentul modifică un caracter, scrie textul după fiecare modificare. Un tablou inițializat parțial, char s[10] = "ab";, are pozițiile rămase completate cu '\0': strlen(s) este 2, dar sizeof(s) este 10. Dacă un caracter din interiorul textului este înlocuit cu '\0', textul se termină acolo: din "ana", după s[1] = '\0', strlen devine 1.

Exemplu în formatul examenului. Ce se afișează în urma executării secvenței de mai jos?

char s[] = "abc";
cout << strlen(s) << ' ' << sizeof(s) << ' ' << (int)s[3];
  • a) 3 3 0
  • b) 3 4 0
  • c) 4 4 0
  • d) 3 4 99

Răspunsul corect este b). Tabloul s are 4 poziții, deoarece inițializarea cu "abc" adaugă terminatorul. strlen(s) numără caracterele dinaintea terminatorului, adică 3, sizeof(s) este 4, iar s[3] este terminatorul, cu codul 0. Varianta a) uită terminatorul în dimensiune, varianta c) îl numără în lungime, iar varianta d) confundă terminatorul cu litera 'c', al cărei cod este 99.

Urmărire pe un șir mic. Fie char s[] = "aB1"; și bucla for (int i = 0; i < strlen(s); i++) if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 32;. Pentru , 'a' are codul 97, iar este codul lui 'A'. Pentru , 'B' are codul 66, în afara intervalului literelor mici, deci rămâne neschimbat. Pentru , '1' nu este literă. Șirul final este "AB1", iar lungimea lui a rămas 3.

Unde apare la examen

La Bacalaureatul la informatică, matematică-informatică, programa de examen cuprinde tipul șir de caractere, cu operatorii, procedurile și funcțiile predefinite pentru citire, afișare, concatenare, căutare, extragere, inserare, eliminare și conversii între șir și valoare numerică (anexa 2 la OMECTS 4800/2010). La sesiunea din iunie–iulie 2026, al doilea exercițiu al Subiectului al III-lea (10 puncte) a cerut un program C/C++ care citește un cuvânt și verifică o proprietate a literelor aflate pe poziții consecutive. Formatul descris este cel din 2026; potrivit proiectului de ordin pentru Bacalaureatul 2027, programa rămâne aceeași.

Pe programa școlară veche, șirurile de caractere sunt la clasa a XI-a, împreună cu structurile de date neomogene (OMECI 5099/2009). Pe programa nouă, aplicată din 2027–2028, ele trec în clasa a X-a, cu clasa str din Python.

Greșeli frecvente

  • Greșit: 'A' și "A" sunt același lucru.
    Corect: primul este un caracter, al doilea un șir de lungime 1, cu terminator.
  • Greșit: strlen("ana") este 4, pentru că tabloul are 4 poziții.
    Corect: strlen numără doar caracterele dinaintea terminatorului, deci 3.
  • Greșit: două șiruri C se compară cu ==.
    Corect: == compară adresele; conținutul se compară cu strcmp.
  • Greșit: 'A' și "A" au același tip.
    Corect: primul este caracter, al doilea este șir.
  • Greșit: "123" este automat întregul 123.
    Corect: este text.
  • Greșit: un tablou char[3] poate stoca șirul C "ana" complet.
    Corect: este nevoie și de poziția terminatorului; pentru 100 de caractere se declară char s[101], altfel terminatorul se scrie în afara tabloului.
  • Greșit: cin >> s citește un text cu spații.
    Corect: citește doar primul cuvânt; pentru o linie întreagă se folosește cin.getline(s, 101).
  • Greșit: a == b compară conținutul a două tablouri de char, iar s = t copiază un șir.
    Corect: a == b compară adrese, deci se folosește strcmp(a, b) == 0; un tablou nu se poate atribui, deci copierea se face cu strcpy(s, t).
  • Greșit: strlen(s), calculat o dată înainte de o ștergere, rămâne valabil.
    Corect: după o ștergere lungimea se schimbă; fie o recalculezi, fie parcurgi până la terminator, ca în exemplul 4.
  • Greșit: după ștergerea de pe poziția se trece la .
    Corect: se sare peste caracterul care a venit pe poziția .
în contul tăuPremium

Testează-te pe această lecție

Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.

Înainte și după

Întrebări frecvente

Cum citesc în C++ un text care conține spații?
Cu cin.getline(s, 101); pentru un tablou char s[101]. Instrucțiunea cin >> s citește doar până la primul spațiu, adică un singur cuvânt.
Ce returnează strcmp?
strcmp(a, b) returnează 0 dacă șirurile sunt egale, o valoare negativă dacă a este înaintea lui b în ordinea dată de codurile caracterelor și o valoare pozitivă dacă a este după b. Literele mari au coduri mai mici decât cele mici, deci „Zebra” este înaintea lui „ana”.
Cum transform o cifră-caracter în număr?
Scazi codul caracterului '0': dacă c este '7', atunci c - '0' este 7. Invers, cifra 7 devine caracterul '0' + 7.

Surse și referințe

Redactare proprie, conform programei:

  • OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa X intensiv; rocnee.eu
  • OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa XI; plan de încadrare: OMEC 7723/2024, anexa 2, tabelele 1–25, legislatie.just.ro; filiera tehnologică: OMEC 7724/2024, anexa 4, tabelul calificării, legislatie.just.ro
  • UNSTPB, Regulament admitere licență 2026, Anexa II-1.2 p. Anx II-14 și Anexa XI-3 p. Anx XI-6–7 (PDF p. 64, 120–121); admitere.pub.ro
  • OMECTS 4800/2010, anexa 2, Informatică, p. 3–4; edu.ro

Documente consultate

  • UNSTPB, admitere 2026, anexa XI-3, p. Anx XI-6–7
  • Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu
  • Programa de bacalaureat la informatică, matematică-informatică (anexa 2 la OMECTS 4800/2010), Ministerul Educației, p. 3–4; edu.ro
  • Subiectele și baremele Bacalaureatului 2026; subiecte2026.edu.ro
  • Proiect de ordin privind organizarea și desfășurarea Bacalaureatului, calendar 2027, Ministerul Educației; edu.ro

Desene: Redactare proprie (desen original), conform Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu

lecțiile sunt gratuite

Ai citit lecția. Acum verifică-te.