De ce contează?
Un singur char e o literă pe o bilă: încape exact un simbol și nimic mai mult. Dar un cuvânt nu e o singură literă — e o panglică de litere lipite în ordine. Tipul string este chiar panglica asta: ține câte litere vrei tu, una după alta, și se lungește sau se scurtează singur când o ai nevoie. Nu mai numeri tu locurile dinainte: panglica își ajustează singură lungimea.
Ce este
Un string este un șir de caractere de lungime variabilă — adică un text. În interior nu e nimic magic: e o secvență de char-uri așezate la rând, exact ca o panglică de litere. Diferența esențială față de un singur char e că string poate ține de la zero litere (text gol) până la mii de litere, iar tu nu trebuie să spui dinainte câte.
Câteva texte sunt string-uri: "ana", "Salut, lume!", "x", chiar și "" (textul gol). Toate au același tip; se deosebesc doar prin lungime și conținut.
Un string este, în esență, un vector de char care își gestionează singur lungimea. Aici stă marea diferență față de tablourile de caractere din C (char nume[100]): la char[] tu rezervi un număr fix de locuri și ai grijă de marcajul de final, iar dacă textul nu încape, ai depășit memoria. La string nu te interesează nimic din toate astea — adaugi litere și se mărește, ștergi și se micșorează. Lungimea o știe el, oricând, prin .size().
Cum arată
Hai să luăm un text concret: "algoritmica". El are 11 litere. Fiecare literă stă pe o poziție numerotată, exact ca un vector — prima poziție este 0, nu 1.
a | l | g | o | r | i | t | m | i | c | a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
s[0]=a |
Din diagramă citești direct trei lucruri care apar la fiecare problemă cu texte:
- s[0] este
'a'— primul caracter, pentru că numărătoarea pornește de la 0. - s[10] este
'a'— ultimul caracter; ultima poziție este mereus.size() - 1, nus.size(). - s.size() este
11— numărul de litere. Pozițiile valide sunt deci0, 1, ..., 10.
Reține perechea asta: dacă textul are lungimea n, pozițiile merg de la 0 la n - 1. Poziția n nu există — e prima capcană la accesul cu s[i].
Implementare C++
Mai întâi declararea și citirea. Aici e prima decizie importantă: vrei un singur cuvânt sau o linie întreagă? cin cu operatorul de extragere se oprește la primul spațiu, deci citește un cuvânt; getline citește toată linia, inclusiv spațiile.
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s; // citeste un singur cuvant (se opreste la spatiu)
cout << s << "\n"; // pentru intrarea "ana maria" afiseaza: ana
string linie;
getline(cin, linie); // citeste restul liniei: " maria"
cout << linie << "\n";
return 0;
}Acum operațiile de bază pe un text deja citit. Lungimea, accesul la un caracter, concatenarea și compararea:
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "algoritmica";
// lungimea: size() si length() fac exact acelasi lucru
cout << s.size() << "\n"; // 11
cout << s.length() << "\n"; // 11
// acces la un caracter prin pozitie (de la 0)
cout << s[0] << "\n"; // a
cout << s[s.size() - 1] << "\n"; // a (ultimul)
// concatenare cu +
string a = "abc";
string b = "de";
string c = a + b;
cout << c << "\n"; // abcde
// comparare lexicografica cu operatorul mai-mic
// "ana" vine inaintea lui "banana" pentru ca 'a' < 'b'
if (a < c) {
cout << "abc vine primul\n"; // se afiseaza (a < ab...)
}
return 0;
}Compararea cu operatorul de mai-mic merită o vorbă, pentru că nu compară lungimi, ci ordinea din dicționar (lexicografică). Calculatorul ia litera 0 din ambele cuvinte: dacă diferă, cuvântul cu litera mai „mică" în alfabet e mai mic și gata. Dacă sunt egale, trece la litera 1, și tot așa. La "ana" față de "banana", prima literă decide: 'a' este înaintea lui 'b', deci "ana" este mai mic decât "banana" — chiar dacă "banana" are mai multe litere. Lungimea contează doar când un cuvânt e prefix al celuilalt: "an" este mai mic decât "ana", fiindcă primul „se termină" mai devreme.
Două capcane apar mereu la texte.
Prima: amesteci cin cu getline. După ce ai citit un număr sau un cuvânt cu cin, în buffer rămâne caracterul de linie nouă pe care l-ai apăsat cu Enter. Următorul getline îl găsește imediat și îți întoarce o linie goală, fără să mai aștepte ce scrii tu. Soluția: după cin, golește restul liniei cu cin.ignore() înainte de getline.
A doua: folosești == pe char[] crezând că ești pe string. Pe string, s1 == s2 compară corect conținutul. Pe un tablou de caractere din C (char a[100]), == compară adresele din memorie, nu literele — aproape mereu îți dă fals chiar dacă textele sunt identice (acolo se folosește strcmp). Cât stai pe string, scapi de tot acest tip de eroare: ==, mai-mic și + lucrează direct pe text.