De ce contează?
Gândește-te la un șirag de mărgele pe care îl porți la mână. Fiecare mărgea are o poziție clară — prima, a doua, a treia — și le citești în ordine, de la un capăt la altul. Dar marele avantaj e altul: dacă vrei să mai adaugi o mărgea, doar o înșiri la capăt, fără să te întrebi „mai am loc pe ață?". Tipul string din C++ este exact acest șirag inteligent de caractere: stă în ordine, are poziții numerotate și se lungește singur când mai adaugi.
Intuiția
Un string este un șir de caractere de lungime variabilă: poate ține cuvântul da (2 litere) sau o propoziție întreagă, fără să-i spui dinainte cât de mare să fie. El își gestionează singur memoria — dacă adaugi caractere, se redimensionează în culise. Tu doar lucrezi cu el, nu cu memoria din spate.
Ce este
În limbajul C „clasic", un text se ținea într-un tablou de caractere: char nume[100]. Asta înseamnă că tu decideai dinainte câte litere încap (aici 100) și tot tu trebuia să marchezi sfârșitul textului cu un caracter special. Dacă textul real era mai lung decât ai prevăzut, programul se strica.
Tipul string din C++ (din biblioteca <string>) rezolvă toate astea pentru tine:
- Lungime variabilă — nu fixezi o capacitate; șirul crește sau scade după nevoie.
- Se gestionează singur — alocarea și eliberarea memoriei se fac automat.
- Știe cât e de lung — îți spune oricând câte caractere are, fără să numeri.
- Se comportă ca o valoare — îl copiezi cu
=, îl lipești cu+, îl compari cu operatori, ca pe un număr obișnuit.
Diferența esențială față de tabloul de char din C: la char nume[100] TU răspunzi de memorie și de lungime, iar un text prea lung iese din tablou și strică alte date. La string, șirul își ține singur evidența lungimii și se redimensionează automat. Asta îl face și mai sigur, și mai comod.
Cum arată
Un string este, în interior, o secvență de caractere așezate pe poziții numerotate de la 0. Cuvântul algoclar arată exact ca un șirag de mărgele: opt caractere pe indicii 0..7.
a | l | g | o | c | l | a | r |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
s[0] |
a | l | g | o | c | l | a | r |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
s[4] |
Lungimea șirului este 8, iar caracterele valide stau pe indicii de la 0 la 7. Ultimul caracter este, prin urmare, s[length() - 1], adică s[7], litera r. Această numerotare de la zero este aceeași ca la vectori — un string se comportă, la accesare, ca un vector de caractere.
Implementare C++
Hai să le punem cap la cap: declarare, două feluri de citire, lungime, indexare și concatenare.
#include <iostream>
#include <string>
using namespace std;
int main() {
string s; // string gol, fara sa fixam o capacitate
cin >> s; // citeste UN SINGUR cuvant (se opreste la spatiu)
cout << s << "\n"; // afiseaza tot sirul
cout << s.length() << "\n"; // numarul de caractere
cout << s[0] << "\n"; // primul caracter
cout << s[s.length() - 1]; // ultimul caracter
return 0;
}Citirea unui cuvânt vs. a unei linii întregi. Cele două forme de citire fac lucruri diferite:
- Operatorul
>>(cin >> s) citește un singur cuvânt: sare peste spațiile de la început și se oprește la primul spațiu, tab sau sfârșit de linie. Pentru intrareamere si pere, el pune însdoarmere. - Funcția
getline(cin, s)citește o linie întreagă, inclusiv spațiile dintre cuvinte, până laEnter. Pentru aceeași intrare, ea pune înstot textulmere si pere.
#include <iostream>
#include <string>
using namespace std;
int main() {
string linie;
getline(cin, linie); // citeste toata linia, cu tot cu spatii
cout << linie << "\n";
cout << linie.length(); // pentru "mere si pere" -> 12 (spatiile conteaza)
return 0;
}Lungime, indexare, concatenare. Ai două funcții echivalente pentru lungime: s.length() și s.size() returnează același lucru — alege oricare. Accesul la un caracter se face cu s[i], iar lipirea a două șiruri se face direct cu +:
#include <iostream>
#include <string>
using namespace std;
int main() {
string a = "algo";
string b = "clar";
string c = a + b; // concatenare: "algoclar"
cout << c << "\n"; // algoclar
cout << c.size() << "\n";// 8 (size si length sunt identice)
c[0] = 'A'; // schimbam un caracter pe loc
cout << c << "\n"; // Algoclar
return 0;
}Observă cât de natural se citește totul: a + b lipește două șiruri ca și cum ai aduna, iar c[0] = 'A' schimbă o literă fix ca la un vector. Nicăieri nu te atingi de memorie — string o face pentru tine.
Cea mai frecventă capcană apare când amesteci citirea unui număr cu citirea unei linii. Dacă scrii cin >> n; și imediat apoi getline(cin, s);, vei observa că s rămâne gol. Motivul: după ce >> citește numărul, lasă caracterul Enter necitit pe linie, iar getline îl întâlnește instant și se oprește, crezând că linia s-a terminat. Soluția: după cin >> n consumă acel Enter cu cin.ignore();, apoi apelează getline. A doua capcană: nu uita că cin >> s ia doar PRIMUL cuvânt — dacă vrei și restul propoziției, ai nevoie de getline.