Șiruri de caractere

Clasa string a fost prezentată pe scurt într-un capitol anterior. Este o clasă foarte puternică de manipulare și prelucrare a șirurilor de caractere. Totuși, deși string-urile sunt secvențe de caractere, le putem reprezenta și va tablouri unidimensionale cu elemente de tip caracter.

De exemplu, următorul:

1
char foo [20];

este un tablou care poate memora până la 20 de elemente de tip char. El poate fi reprezentat astfel:


De aceea, acest tablou are capacitatea de a stoca o secvență de până la 20 de caractere. Dar nu este necesar ca limita aceasta să fie atinsă: tabloul poate reține și o secvență mai scurtă. De exemplu, la un moment dat în program, poate fi stocată oricare dintre secvențele "Hello" sau "Merry Christmas" în foo, deoarece oricare dintre ele reprezintă o secvență de până la 20 de caractere.

Prin convenție, sfârșitul string-urilor reprezentate ca secvențe de caractere este marcat de un caracter special: caracterul null, a cărui valoare literală poate fi scrisă ca '\0' (backslash, zero).

În acest caz, tabloul de 20 de elemente de tip char denumit foo poate fi reprezentat ca memorând secvența de caractere "Hello" and "Merry Christmas" as:


Să observăm că după conținutul propriu al șirului de caractere se adaugă un caracter nul ('\0') pentru a indica sfârșitul secvenței. Panourile de culoare gri reprezintă elemente de tip char cu valori nedeterminate.

Inițializarea unei secvențe de caractere terminate cu un caracter nul

Deoarece tablourile de caractere sunt tablouri obișnuite, ele respectă aceleași reguli ca și acestea. De exemplu, pentru a inițializa un tablou de caractere cu o secvență predeterminată de caractere, o putem face ca pe o inițializare a oricărui alt tablou:

1
char cuvant[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

Mai sus se declară un tablou de 6 elemente de tip char inițializat cu caracterele care formează cuvântul "Hello" plus un caracter nul '\0' la sfârșit.

Dar tablourile cu elemente caracter au și o altă modalitate de a fi inițializate: folosirea directă a literalilor string.

În unele exemple pe care le-am folosit în capitolele anterioare, literalii string au apărut deja de câteva ori. Aceștia sunt precizați prin includerea textului între ghilimele ("). De exemplu:

1
"rezultatul este: "

Acesta este un literal string, folosit într-unul din exemplele anterioare.

Secvențele de caractere cuprinse între ghilimele (") sunt literali constanți. Și tipul lor este, de fapt, un tablou de caractere terminat cu caracterul nul. Aceasta înseamnă că literalii string au întotdeauna un caracter nul adăugat la sfârșit ('\0').

De aceea, tabloul cu elemente de tip char denumit cuvant poate fi inițializat cu o secvență de caractere terminată cu un caracter nul cu ajutorul uneia dintre următoarele două propoziții:

1
2
char cuvant[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char cuvant[] = "Hello";

În ambele cazuri, tabloul de caractere cuvant este declarat ca având dimensiunea de 6 elemente de tip char: 5 caractere care compun cuvântul "Hello", plus caracterul nul ('\0') de la final, care specifică sfârșitul secvenței și, la fel, în al doilea caz la folosirea ghilimelelor, când este adăugat automat.

Vă rog să observați că vorbim despre inițializarea unui tablou de caractere chiar în momentul declarării și nu despre atribuirea de valori ulterior (după declarație). De fapt, datorită faptului că literalii string sunt tablouri obișnuite, au aceleași restricții ca și acestea și nu li se pot atribui valori.

Expresii (ce apar ulterior declarației, așa cum am făcut cu cuvant), precum:

1
2
cuvant = "Bye";
cuvant[] = "Bye";

nu sunt valide, așa cum nu este nici:

1
cuvant = { 'B', 'y', 'e', '\0' };

Motivul este că tablourilor nu li se pot atribui valori. Totuși, să observăm că fiecăruia dintre elementele tabloului i se poate atribui câte o valoare individual. De exemplu, este corect:

1
2
3
4
cuvant[0] = 'B';
cuvant[1] = 'y';
cuvant[2] = 'e';
cuvant[3] = '\0';

String-uri și secvențe terminate cu caracterul nul

Tablourile simple de secvențe terminate cu caracterul nul sunt cel mai uzual tip folosit în limbajul C pentru a reprezenta string-uri (de aceea mai sunt cunoscute și ca string-uri C). În C++, chiar dacă biblioteca standard definește tipuri specifice pentru string-uri (clasa string), folosirea tablourilor simple de secvențe terminate cu caracterul nul (string-uri C) este încă un mod natural de reprezentare; de fapt, literalii string produc secvențe terminate cu caracterul nul și nu obiecte string.

În biblioteca standard, ambele reprezentări pentru string-uri (string-uri C și string-uri de bibliotecă) coexistă și cele mai multe funcții de prelucrare a șirurilor sunt supraîncărcate pentru a le suporta pe ambele.

De exemplu, cin și cout suportă direct secențe terminate cu caracterul nul, permițând extragerea lor directă din cin sau inserarea în cout, exact cum se întâmplă și cu string-uri. De exemplu:

// strings and NTCS:
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  char intrebare1[] = "Cum te numesti? ";
  string intrebare2 = "Unde locuiesti? ";
  char raspuns1 [80];
  string raspuns2;
  cout << intrebare1;
  cin >> raaspuns1;
  cout << intrebare2;
  cin >> raspuns2;
  cout << "Hello, " << raspuns1;
  cout << " din " << raspuns2 << "!\n";
  return 0;
}
Cum te numesti? Homer
Unde locuiesti? Greece
Hello, Homer din Greece!

În acest exemplu, am folosit atât tablou de caractere cu secvență terminată cu caracter nul cât și string-uri. Se pot chiar interschimba la folosirea cu cin și cout, dar există o mare diferență în privința declarațiilor: tablourile au dimensiune fixă ce trebuie precizată implicit sau explicit în declarație; intrebare1 are exact 20 de caractere (inclusiv caracterul nul de terminare) și raspuns1 are dimensiunea de 80 de caractere; când șirurile sunt pur și simplu string-uri, nu se specifică nici o dimensiune. Aceasta se întâmplă datorită faptului că string-urile au dimensiune dinamică determinată în timpul executării programului, față de tablouri la care dimensiunea este determinată la compilare, înainte ca programul să se execute.

În oricare dintre cazuri, secvențele de caractere terminate cu caracterul nul și tablourile sunt ușor transformate de la unul la altul:

Secvențe terminate cu caracterul nul pot fi transformate implicit în string-uri și string-urile pot fi transformate în secvențe terminate cu caracterul nul prin folosirea fie a a funcțiilor membru din string c_str sau data:

1
2
3
4
char myntcs[] = "un text";
string mystring = myntcs;  // convertește c-string la string
cout << mystring;          // printat ca un string din bibliotecă
cout << mystring.c_str();  // printat ca un c-string 

(notă: c_str și data din string sunt echivalente)
Index
Index