Sari la conținut
Înapoi la teorie

Teorie

Șiruri de caractere la atestatul de informatică

Citirea unui text cu getline, parcurgerea până la terminator, numărarea cuvintelor cu flag, filtrarea caracterelor și compararea cu strcmp — cu problemele de atestat în care apar.

4

minute de citit

8

secțiuni

38

probleme rezolvate legate

Actualizat pe .

Pe această pagină
  1. Citirea unui text
  2. Tehnica 1 — Numărarea cuvintelor cu flag
  3. Tehnica 2 — Filtrarea caracterelor
  4. Tehnica 3 — Teste pe caractere
  5. Tehnica 4 — Compararea cuvintelor
  6. Greșeli care se repetă
  7. Unde exersezi mai departe
  8. Toate problemele din această categorie

Subiectele cu text par variate, dar se reduc la patru tehnici. Cele mai multe puncte se pierd nu pe logică, ci pe două detalii tehnice: cum citești textul și cât de mare declari șirul.

Citirea unui text

C++
char s[201];
cin.getline(s, 201);        // de la tastatura
f.getline(s, 201);          // dintr-un fisier

getline, nu >>. Operatorul >> se oprește la primul spațiu, deci ai prelua doar primul cuvânt — iar la problemele care numără cuvinte ai obține mereu 1. getline ia tot rândul, cu spații și semne de punctuație.

Dimensiunea e cu unu mai mare decât maximul din enunț. „Cel mult 200 de caractere" înseamnă char s[201]: mai trebuie un loc pentru terminatorul '\0', pe care C++ îl adaugă automat la final. Cu char s[200] scrii în afara șirului la un text de exact 200 de caractere.

Parcurgerea merge până la terminator, deci nu ai nevoie de lungime:

C++
for (int i = 0; s[i] != '\0'; i++) { /* ... */ }

Tehnica 1

Numărarea cuvintelor cu flag

Ideea tentantă „numărul de cuvinte = numărul de spații + 1" e greșită imediat ce textul începe sau se termină cu spațiu — exact ce testează enunțurile.

Metoda corectă numără tranzițiile de la separator la literă:

C++
int nr = 0;
bool inCuvant = false;

for (int i = 0; s[i] != '\0'; i++)
    if (s[i] != ' ') {
        if (!inCuvant) nr++;        // tocmai am intrat intr-un cuvant nou
        inCuvant = true;
    } else {
        inCuvant = false;
    }

Flagul reține unde te afli. Incrementarea se face doar la intrarea într-un cuvânt; literele următoare nu mai numără nimic, pentru că flagul e deja true.

Metoda tratează automat toate cazurile-limită: spații la început, spații la final, spații multiple, text gol.

Tehnica 2

Filtrarea caracterelor

Pentru „elimină X din șir", nu ștergi caractere — construiești un șir nou cu ce păstrezi, folosind doi indici care avansează independent:

C++
int k = 0;
for (int i = 0; s[i] != '\0'; i++)
    if (!deSters(s[i])) rezultat[k++] = s[i];
rezultat[k] = '\0';             // OBLIGATORIU

i parcurge tot, k avansează doar când chiar scrii. E aceeași tehnică ca la filtrarea vectorilor, aplicată caracterelor.

Terminatorul de la final e obligatoriu. Fără rezultat[k] = '\0', afișarea continuă în memorie dincolo de șir și apar caractere aleatorii.

Exersează pe subiecte reale

Tehnica 3

Teste pe caractere

Caracterele sunt numere. În tabela ASCII, grupurile sunt consecutive, deci testele devin comparații de interval:

C++
if (c >= '0' && c <= '9')   // cifra
if (c >= 'a' && c <= 'z')   // litera mica
if (c >= 'A' && c <= 'Z')   // litera mare

Ghilimelele simple contează: '0' e caracterul zero (cod 48), nu numărul 0.

Conversia majusculă → minusculă se face adunând 32, pentru că literele mici sunt cu exact atât mai departe ('A' = 65, 'a' = 97):

C++
if (c >= 'A' && c <= 'Z') c = c + 32;

Verificarea intervalului e necesară — altfel strici cifrele și semnele de punctuație. Tehnica e utilă oriunde enunțul cere și majuscule, și minuscule: în loc de zece comparații pentru vocale, converteşti și compari cu cinci.

Exersează pe subiecte reale

Tehnica 4

Compararea cuvintelor

C++
#include <cstring>

if (strcmp(cuvant, cautat) == 0) nr++;

Două capcane, ambele frecvente:

  • == nu merge pe șiruri de caractere. Compară adresele din memorie, nu conținutul, iar rezultatul e aproape întotdeauna fals.
  • strcmp returnează 0 la egalitate, nu 1. Valoarea returnată e diferența în ordine alfabetică: negativă, zero sau pozitivă.

Exersează pe subiecte reale

Greșeli care se repetă

  • cin >> s în loc de getline — se citește doar primul cuvânt
  • char s[200] pentru „cel mult 200 de caractere" — lipsește locul terminatorului
  • Numărarea spațiilor + 1 — greșit la spații de la început sau final
  • Terminatorul '\0' uitat după construirea unui șir nou
  • cuvant == cautat în loc de strcmp
  • strcmp(...) == 1 — funcția returnează 0 la egalitate
  • Conversia c + 32 fără verificarea intervalului — strică cifrele
  • Rânduri goale la separatori multipli, din lipsa testului if (inCuvant)

Mai departe

Unde exersezi mai departe

Lucrul cu șiruri are multe capcane mici (delimitatori, indici, funcții de bibliotecă), iar un evaluator automat le prinde imediat.

Pentru asta, pbinfo.ro e cea mai bună resursă românească: peste 2500 de probleme de informatică cu evaluator automat, și o trimiți la testat direct din browser. E construită pentru olimpiadă și bacalaureat, deci se completează cu ce găsești aici — noi acoperim subiectele de atestat, cu rezolvări scrise.

Toate problemele din această categorie

Fiecare are rezolvare completă în C++, explicată pas cu pas.

38Arată toate problemele rezolvate38 programare