De ce contează?
Un string din C++ nu e doar un șir de litere pe care le ții într-o cutie — vine cu o trusă de unelte gata făcute. Așa cum o trusă de scule are ruletă, foarfece, lupă și pix, string are funcții care îți măsoară lungimea, taie o bucată, caută un cuvânt sau lipesc două șiruri. Nu trebuie să-ți construiești tu uneltele de la zero: trebuie doar să știi ce face fiecare și când o folosești.
Ce este
În C++, string din biblioteca standard este mai mult decât o înșiruire de caractere: este un obiect care aduce cu el o mulțime de metode (funcții apelate cu punct, de forma s.functie(...)). În loc să scrii manual o buclă ca să afli lungimea sau ca să cauți un caracter, ceri direct obiectului să facă treaba.
Iată uneltele pe care le folosești cel mai des:
s.length()/s.size()— câte caractere are șirul (sunt identice).s.substr(poz, len)— întoarce o copie a sub-șirului care începe la pozițiapozși arelencaractere. Dacă omițilen, ia tot până la final.s.find(sub)— cautăsubînsși întoarce poziția primei apariții, saustring::nposdacă nu există.s.insert(poz, text)— insereazătextîncepând de la pozițiapoz.s.erase(poz, len)— ștergelencaractere începând de la pozițiapoz.s.replace(poz, len, text)— înlocuieștelencaractere de lapozcutext.s.front()/s.back()— primul, respectiv ultimul caracter.a + b— concatenare (lipește două șiruri).a == b,a < b— comparare pe caractere;mai mic decatînseamnă „înainte în ordinea de dicționar" (lexicografic).stoi(s)/to_string(x)— conversie din string în întreg, respectiv din număr în string.
find nu întoarce niciodată -1 când nu găsește nimic — întoarce o valoare specială, string::npos (un număr foarte mare). De aceea testul corect este if (s.find(sub) == string::npos), nu if (s.find(sub) == -1). Verifică mereu acest caz înainte să folosești poziția găsită.
Cum arată
Hai să vedem fiecare unealtă la lucru pe același exemplu: șirul algoritmica (11 caractere, pozițiile merg de la 0 la 10).
| Funcție | Ce face | Exemplu și rezultat |
|---|---|---|
s.length() | numărul de caractere | 11 |
s.substr(0, 4) | taie 4 caractere de la poziția 0 | "algo" |
s.substr(4) | tot de la poziția 4 încolo | "ritmica" |
s.find("rit") | poziția primei apariții | 4 |
s.find("xyz") | nu există | string::npos |
s.front() | primul caracter | 'a' |
s.back() | ultimul caracter | 'a' |
s.erase(0, 4) | șterge primele 4 | "ritmica" |
s.replace(4, 3, "GOR") | înlocuiește "rit" cu "GOR" | "algoGORmica" |
"algo" + "ritm" | concatenare | "algoritm" |
to_string(2026) | număr în string | "2026" |
stoi("2026") | string în număr | 2026 |
Observă cum substr și find lucrează împreună: find îți spune unde începe ceva, iar substr taie de acolo. Diagrama de mai jos arată pozițiile din algoritmica — find("rit") întoarce 4 pentru că exact acolo începe sub-șirul căutat.
a | l | g | o | r | i | t | m | i | c | a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
find=4 |
Implementare C++
Programul de mai jos pune cap la cap uneltele importante și pune rezultatul fiecăreia în comentariu, ca să poți verifica.
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "algoritmica";
// lungimea sirului
cout << s.length() << "\n"; // 11
// substr(pozitie, lungime): taie o bucata
cout << s.substr(0, 4) << "\n"; // algo
cout << s.substr(4) << "\n"; // ritmica (pana la final)
// find: pozitia primei aparitii sau string::npos
int p = s.find("rit");
cout << p << "\n"; // 4
if (s.find("xyz") == string::npos)
cout << "negasit\n"; // negasit
// primul si ultimul caracter
cout << s.front() << " " << s.back() << "\n"; // a a
// replace(pozitie, lungime, text): schimba o bucata
string t = s;
t.replace(4, 3, "GOR");
cout << t << "\n"; // algoGORmica
// concatenare cu +
string nume = "algo" + string("ritm");
cout << nume << "\n"; // algoritm
// comparare lexicografica: "abc" < "abd" este adevarat
cout << ("abc" < string("abd")) << "\n"; // 1
// conversii intre string si numar
int an = stoi("2026") + 1;
cout << to_string(an) << "\n"; // 2027
return 0;
}Reține că find întoarce poziția ca un index întreg, iar substr și replace primesc întâi poziția și apoi lungimea. Conversiile stoi și to_string sunt esențiale când citești numere „lipite" de text și vrei să le aduni sau să le tipărești înapoi.
Două capcane care strică multe soluții cu string:
- Uiți să verifici
string::npos. Dacă scriiint p = s.find("xyz");și apoi foloseștis.substr(p, ...)fără să verifici,peste un număr uriaș (npos), iarsubstrva arunca o eroare sau va da un rezultat aberant. Verifică mereu:if (s.find(sub) == string::npos). - Indici în afara lungimii.
s.substr(poz, len),s.erase,s.replaceșis.back()presupun că poziția chiar există. Pe un șir gols.back()e comportament nedefinit, iars.substr(20, 3)pe un șir de 11 caractere aruncă o eroare. Verifică întâis.length()înainte să atingi o poziție mare.