Curs C++ | Sectiunea 26 – Strings (Bazele)
❓ Un string reprezinta un set de caractere. Urmeaza atunci intrebarea, de ce mai avem nevoie din moment ce exista deja un tip de date pentru acest aspect, si anume char?
💡 Variabilele de tip char sunt utile in general cand avem nevoie sa procesam caracterele individual. Pe de alta parte, devine destul de dificil cand avem date ce contin siruri de caractere reprezentand nume, informatii sau pur si simplu text, procesarea acestora fiind destul de inceata.
Vom invata pe parcurs ca un string nu este ca orice alt tip de date folosit pana acum, acesta fiind primul nostru contact cu notiunea de obiecte si cu programarea orientata pe obiecte (object-oriented programming/ OOP). Vom spune pentru moment doar ca string-urile pe care le vom folosi sunt obiecte de tip string.
In exemplul de mai sus am declarat o variabila string nume_familie, cu un rol evident.
❗ Tineti cont, asa cum am spus anterior, tipul string nu este un built-in type. Daca vrem sa-l folosim, suntem nevoiti sa adaugam directiva de preprocesare #include la inceputul programului si sa cerem ca un fisier header (header file) numit string sa fie inclus in timpul compilarii.
📝 Mai putem adauga si faptul ca string nu este un keyword, precum alte tipuri (int, float etc) folosite pana acum.
Initializare
💡 Putem initializa un string in acelasi mod pe care l-am folosit si la tipurile clasice, prin operatorul de asignare urmat de un string literal (un set de caractere inclus in ghilimele). Nu uitati insa, apostroful este folosit numai pentru caractere individuale, string-ul mereu cu ghilimele.
🥇 Astfel, noii variabile create, nume_familie, ii va fi asignata un string “Popescu”. Aceasta nu este singura informatie stocata in interiorul variabilei, dar vom discuta in curand mai multe.
🔤 Puteti remarca si faptul ca putem folosi cuvantul string cu doua intelesuri diferite: ca un tip de date si ca o entitate ce contine un numar finit de caractere.
🥈 Mai exista, bineinteles, si alta metoda, mult mai potrivita pentru programarea orientata pe obiecte:
❓ Folosim o sintaxa ce poate semana cu invocarea unei functii, cu un set de paranteze si un argument in interior. Te-ai putea intreba daca exista cu un adevarat o functie numita nume_familie? Raspunsul este “da si nu“.
- 👍 Da, pentru ca exista o functie specializata responsabila pentru crearea string-urilor si este invocata de fiecare data cand un nou string este creat
- 👎 Nu, pentru ca nu putem invoca direct acea functie ca oricare alta
Avem posibilitatea si sa initializam un string cu valoarea unei variabile deja existenta.
Concatenare
💡 Ca orice tip de date folosit, tipul string are proprii lui operatori. Unul din cei mai importanti si cel mai frecvent utilizat este operatorul “+” (plus). Atentie, acesta nu aduna string-uri intr-un mod clasic aritmetic, ci le concateneaza. Mai exact, lipeste string-urile intre ele, rezultand la final unul singur.
❗ Mentionam si faptul ca procesul de concatenare + nu este comutativ, spre deosebire adunarea aritmetica.
⛔ Exista o limitare importanta in privinta concatenarii si anume, nu putem concatena literali! Putem concatena orice variabila cu un literal, un literal cu o variabila, o variabila cu alta variabila, dar nu un literal cu un literal.
Observam in urma compilarii programului ca vom primi o eroare: invalid operands of types ‘const char [4]’ and ‘const char [7]’ to binary ‘operator+’ in legatura cu linia 5, unde incercam sa concatenam doi literali.
Avem bineinteles,posibilitatea sa folosim, ca si in cazul operatorului aritmetic +, operatorul prescurtat “+=“. Avand rezultatul asteptat.
Input
Conform exemplelor precedente, putem spune ca afisarea unui string pe ecran este simpla si nu genereaza probleme ascunse. Acest lucru fiind realizat prin stream-ul cout.
😬 Introducerea string-urilor este insa putin mai complicata. Lucru ce se datoreaza din cauza faptului ca stream-ul de date cin considera spatiile goale (nu numai spatiile goale prin “space” dar si asa numitele white spaces) ca delimitatori. Astfel ca putem avea dificulati daca dorim sa inseram si sa stocam un string ce contine in componenta lui astfel de caractere.
Daca luam spre exemplu, urmatorul cod, si inseram un text precum “my name is Alex“, ce contine spatii, output-ul nu va fi cel dorit. Vom observa ca vor fi salvate toate caracterele pana la intalnirea primului spatiu.
💡 Totusi, pentru a rezolva aceasta problema suntem nevoiti sa folosim o noua functie, getline. Aceasta citeste toate caracterele fara a le distinge intre ele, exceptand caracterul ce reprezinta Enter (key character), marcand astfel finalul liniei. Rezultatul acum va fi cel dorit, stocand toata propozitia noastra.
Compararea String-urilor
String-urile, ca orice alte tipuri de date, pot fi comparate. Cel mai simplu caz de comparare ar fi cand dorim sa verificam daca doua variabile de tip string contin string-uri identice.
🔒 Simulam un un caz real, dorim sa ne conectam pe contul nostru si trebuie sa introducem parola. Daca parola introdusa va fi identica cu cea stocata in baza de date, atunci ne putem conecta, altfel nu.
💡 In scopul rezolvarii acestei probleme, folosim operatorul nostru deja stiut de egaliate “==“.
Exista, bineinteles, si posibilitatea sa comparam doua string-uri intr-un mod mai flexibil. Folosim operatorii specifici de comparare a datelor, “>“, “<“, “>=“, “<=“, “!=“.
❗ Atentie, acesti operatori, cand sunt folositi impreuna cu string-urile, compararea are loc raportata la ordinea alfabetica, unde ‘a‘ este mai mare deca ‘A‘, sau spre exemplu, ‘a‘ este mai mare ca ‘1‘. Daca nu sunteti siguri de ordinea alfabetica, verificati tabelul ASCII.
Sortarea unui string
🔢 Parcurgem un exemplu practic, avem un string si vrem sa-l sortam in ordine alfabetica. Pentru a rezolva aceasta problema vom folosi un algoritm de sortare, il alegem pe cel mai simplu numit Bubble Sort. Nu il vom explica in aceasta sectiune dar nu va faceti probleme, vom avea un curs separat despre algoritmi in care ii vom discuta pe larg 😉 .
Compararea String-urilor – abordarea OOP
Ni se pune la dispozitie o abordare mult mai complexa si puternica pentru a compara string-urile. Aceasta va fi si o buna intrdoucere pentru a vedea stilul de programare orientata pe obiecte.
Pentru varianta clasica de abordare, deobicei avem niste date si un set de functii ce opereaza pe acele date. Suntem obisnuiti cu urmatoarea sintaxa:
💡 Pe de alta parte, prin abordarea OOP, folosim o terminologie usor diferita. Atat datele cat si functiile sunt incorporate in asa numitul obiect. Datele reprezinta proprietatea obiectului sau variabile membre (member variables), iar functiile sunt metodele obiectului (methods) sau functiile membre. Vom reveni la aceste notiuni in curand si le vom discuta in amanunt.
Daca ne dorim ca o metoda specifica (functie membru) sa proceseze date incorporate in obiect, o vom apela in felul urmator:
Vom rescrie programul nostru de verificare a parolei folosind una din numeroasele functii membre ce exista in fiecare obiect string. Metoda este numita “compare” si are un rol evident, compara un string cu altul iar valoarea de return este 0 in cazul in care cele doua sunt identice.
👁️ Dupa cum se poate observa, am inlocuit operatorul de egalitate cu noua metoda. Sintaxa se poate citi in felul urmator: apeleaza metoda compare pentru obiectul stored_password pentru a compara string-ul stocat in interior cu string-ul stocat in obiectul entered_password.
Desigur, posibilitatile de comparare nu se opresc in a verifica identitatea lor. Putem verifica toate posibilele relationari dintre ele dupa cum urmeaza:
| string1.compare(string2) | relatia intre string-urile comparare |
|---|---|
| 0 | string1 == string2 |
| <0 | fie valoarea primului caracter care nu se potrivește este mai mică în șirul comparat, fie toate caracterele comparate se potrivesc, dar șirul comparat este mai scurt |
| >0 | fie valoarea primului caracter care nu se potrivește este mai mare în șirul comparat, fie toate caracterele comparate se potrivesc, dar șirul comparat este mai lung |
Aici se termina si aceasta sectiune. Vom continua in urmatoarea tot despre string-uri 🙂 . Daca aveti intrebari suplimentare puteti folosi informatiile de aici.
➡ Sectiunea anterioara:Curs C++ | Sectiunea 25 – Conversii
➡ Sectiunea urmatoare:Curs C++ | Sectiunea 27 – Strings (Noi functionalitati)

