Tipul string — text ca un vector de caractere

Bază~14 min7 pași

De ce contează?

Gândește-te la un cuvânt scris pe o bandă de pătrățele: fiecare pătrățel ține exact o literă, iar pătrățelele sunt numerotate de la 0. Asta este un string — un șir de caractere așezate unul după altul, fiecare cu poziția lui.

Ce este un string?

Un string este o secvență de caractere stocate în ordine. În C++ ai tipul string din biblioteca standard, care se comportă ca un vector de char, dar cu un mare avantaj: își gestionează singur lungimea și memoria.

Spre deosebire de char s[100], unde tu decizi dimensiunea și ai grijă de terminatorul '\0', un string crește și scade automat și știe mereu câte caractere are.

Observația-cheie

Un string indexat se comportă fix ca un vector: s[0] e primul caracter, s[s.size() - 1] e ultimul. Indecșii merg de la 0 la size() - 1.

Cum arată în memorie

Fie s = "info". Caracterele stau pe poziții consecutive:

s
i
n
f
o
index
0
1
2
3
String-ul „info” are 4 caractere; indecșii valizi sunt 0…3.

Lungimea este s.size() (sau echivalent s.length()) — aici 4. Nu există caracter pe poziția 4; accesul acolo este în afara șirului.

Citire și afișare

Sunt două moduri de citire, și e important să nu le confunzi:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string cuvant;
    cin >> cuvant;           // citeste pana la primul spatiu
    cout << cuvant << "\n";  // afiseaza cuvantul citit

    string linie;
    getline(cin, linie);     // citeste toata linia, cu spatii
    cout << linie << "\n";
    return 0;
}

De ce contează diferența? cin >> cuvant se oprește la primul spațiu, deci pentru intrarea mihai pop citește doar mihai. Dacă vrei numele complet, ai nevoie de getline.

Greșeli frecvente

Capcana clasică: după cin >> n, un getline(cin, s) imediat citește linia goală rămasă (Enterul de după număr). Soluție: consumă restul liniei cu cin.ignore() înainte de getline.

Operații de bază

string suportă lucruri pe care char[] nu le face direct:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string a = "info", b = "matica";
    string c = a + b;            // concatenare -> "informatica"
    cout << c << "\n";           // informatica
    cout << c.size() << "\n";    // 11

    c[0] = 'I';                  // modifici un caracter
    cout << c << "\n";           // Informatica

    if (a < b) cout << "a inainte\n";  // comparatie lexicografica
    return 0;
}

Adunarea (+) lipește două șiruri, comparația (<, ==) se face lexicografic (ca în dicționar), iar c[i] îți dă acces direct la fiecare caracter ca la un vector.

Complexitate

OperațieTimp
s[i] (acces)O(1)
s.size()O(1)
a + b (concatenare)O(lungimea rezultatului)
comparație a < bO(lungimea minimă)
Observația-cheie

s.size() întoarce un tip fără semn (size_t). Într-un for cu scădere, s.size() - 1 pe un șir gol devine un număr uriaș, nu -1. Vezi capcana.

Greșeli frecvente

Greșeli frecvente de concurs:

  • Confuzia 'a' cu "a": ghilimele simple = un singur char; ghilimele duble = string. s = 'a'; nu compilează cum crezi.
  • size() fără semn: for (int i = 0; i <= s.size() - 1; i++) pe șir gol iterează miliarde de pași. Folosește (int)s.size() sau testează i < s.size().
  • Citire amestecată cin >> cu getline fără cin.ignore().
  • Acces în afara șirului: s[s.size()] nu e caracter valid.

Recapitulare

  • Un string e un șir de caractere indexabil de la 0 la size() - 1, care își gestionează singur memoria.
  • cin >> citește un cuvânt; getline(cin, s) citește toată linia, cu spații.
  • Suportă concatenare (+), comparație lexicografică și acces direct s[i].

Întrebarea 1 / 3

Pentru un string `s = "info"`, ce returnează `s.size()`?