De ce contează?
Imaginează-ți că ai în față o trusă de unelte pentru lucrul cu text: o foarfecă ce taie o bucată din mijloc, o lupă ce caută un cuvânt, un creion ce înlocuiește litere și o etichetă care spune dacă un caracter e cifră sau literă. În C++ nu trebuie să-ți construiești singur aceste unelte — std::string și biblioteca <cctype> ți le oferă gata făcute. Trebuie doar să știi pe care s-o apuci.
Ce este
Pe un string poți face mult mai mult decât să-l citești și să-l afișezi. Tipul string vine cu funcții membru — le apelezi cu punct, ca în s.substr(...) — care taie, caută și modifică textul. Cele mai folosite:
s.substr(poz, len)— întoarce un nou șir:lencaractere începând de la pozițiapoz.s.find(sub)— întoarce poziția primei apariții a subșiruluisub, sau valoarea specialăstring::nposdacă nu îl găsește.s.insert(poz, t)— inserează textultîncepând de la pozițiapoz.s.erase(poz, len)— ștergelencaractere începând de lapoz.s.replace(poz, len, t)— înlocuieștelencaractere de lapozcu textult.a + b— concatenează (lipește) două șiruri.
Separat, pentru caractere individuale ai biblioteca <cctype>, cu funcții care primesc un char și răspund o întrebare sau îl transformă:
isalpha(c)— estecliteră? ·isdigit(c)— esteccifră?toupper(c)— varianta mare a literei ·tolower(c)— varianta mică.
Regula de aur: nu reinventa parcurgeri manuale când STL îți oferă deja funcția. Ca să afli dacă „rit" apare în text, nu scrii o buclă dublă care compară caracter cu caracter — apelezi s.find("rit") și gata. Codul devine mai scurt, mai clar și mai greu de greșit. Olimpicul nu rescrie ce există deja optimizat în bibliotecă.
Cum arată
Hai să lucrăm pe șirul s = "algoritmica". Numerotează pozițiile începând de la 0:
a | l | g | o | r | i | t | m | i | c | a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Acum câteva apeluri și ce întorc ele:
a | l | g | o | r | i | t | m | i | c | a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
a | l | g | o | r | i | t | m | i | c | a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
gasit-aici |
Pune-le într-un tabel ca să le ții minte:
| Funcție | Ce face | Exemplu pe „algoritmica" |
|---|---|---|
s.substr(0, 4) | extrage 4 caractere de la poziția 0 | "algo" |
s.substr(4, 3) | extrage 3 caractere de la poziția 4 | "rit" |
s.find("rit") | poziția primei apariții | 4 |
s.find("xyz") | subșir inexistent | string::npos |
s.erase(0, 4) | șterge 4 caractere de la poziția 0 | "ritmica" |
"info" + "gen" | concatenare | "infogen" |
Atenție la substr: al doilea argument este o lungime, nu o poziție de final. s.substr(4, 3) ia 3 caractere (pozițiile 4, 5, 6), nu „până la poziția 3".
Implementare C++
Un program care numără câte cifre are un text, scrie versiunea cu majuscule a literelor și verifică dacă apare un cuvânt. Folosim substr, find, toupper, isdigit într-o buclă:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string s = "cod123algo";
// 1) parcurgem caracter cu caracter
int cifre = 0;
string mari = "";
for (int i = 0; i < (int)s.size(); i++) {
char c = s[i];
if (isdigit(c)) cifre++; // numara cifrele
mari += toupper(c); // construim varianta cu majuscule
}
cout << cifre << "\n"; // 3 (cifrele 1, 2, 3)
cout << mari << "\n"; // COD123ALGO
// 2) extragem o bucata cu substr
cout << s.substr(0, 3) << "\n"; // cod (3 caractere de la pozitia 0)
// 3) cautam un subsir cu find si VERIFICAM rezultatul
int poz = s.find("algo");
if (poz != (int)string::npos)
cout << "gasit la pozitia " << poz << "\n"; // gasit la pozitia 6
else
cout << "nu apare\n";
int poz2 = s.find("xyz");
if (poz2 == (int)string::npos)
cout << "xyz nu apare\n"; // se afiseaza: xyz nu apare
return 0;
}Observă cum tot ce ține de „caut o bucată" sau „transform un caracter" se rezolvă cu un singur apel — nu scriem nicio buclă de comparare manuală.
Trei capcane frecvente:
- Uiți să verifici
find(...) == string::npos. Când subșirul nu există,findîntoarcestring::npos(un număr uriaș). Dacă folosești rezultatul direct ca poziție, fără să verifici, accesezi în afara șirului și obții valori aberante. Verifică mereu întâi dacă s-a găsit. - Confunzi indicele cu lungimea la
substr. Al doilea argument este câte caractere iei, nu până unde.s.substr(2, 5)ia 5 caractere de la poziția 2, nu caracterele dintre pozițiile 2 și 5. touppernu merge pe diacritice. Funcțiile din<cctype>lucrează corect doar pe literele englezea-zșiA-Z. Pe „ă", „ș", „ț" rezultatul este nedefinit — la concurs textele cu diacritice se tratează separat, nu cutoupper.