char[] vs string — două abordări
Un şir de caractere este o secvenţă de litere, cifre sau simboluri stocate consecutiv în memorie. Fiecare caracter are un cod numeric în tabelul ASCII. De exemplu, 'A' = 65, 'a' = 97, '0' = 48.
Imaginează-ţi un şir ca o cutie cu sertare numerotate — fiecare sertar ţine câte un caracter. Ultimul sertar special conţine '\0' (zero), semn că şirul s-a terminat.
Relaţia dintre caractere şi numere permite comparaţii, conversii şi operaţii matematice pe caractere!
Tabela ASCII — caractere esenţiale pentru BAC
| Caracter | Cod ASCII | Utilizare la BAC | Exemplu |
|---|---|---|---|
| A–Z | 65–90 | Litere mari → ch - 'A' = index 0–25 | 'C'-'A' = 2 |
| a–z | 97–122 | Litere mici → ch - 'a' = index 0–25 | 'c'-'a' = 2 |
| 0–9 | 48–57 | Cifre → ch - '0' = cifra (0–9) | '7'-'0' = 7 |
| Spaţiu | 32 | Delimitator cuvânte în getline() | c == ' ' |
| \0 | 0 | Terminator de şir (null char) | s[n] = '\0' |
| A vs a | 65 vs 97 | Diferenţa: 32 → conversie mare/mică | 'a'-'A' = 32 |
Vector de caractere terminat cu '\0'. Funcţii din <cstring>: strlen, strcpy, strcat, strcmp, strchr, strstr.
char s[201] = "salut";Accesare: s[0]='s', s[1]='a', ..., s[5]='\0'
Clasă C++, dimensiune dinamică. Operatori: +, ==, []. Metode: .length(), .substr(), .find(), .erase().
string s = "salut";Accesare: s[0]='s', s.length()=5
// char[] — declarare si initializare char s[201]; // maxim 200 caractere + '\0' char t[] = "informatica"; // dimensiune dedusa: 12 (11 + '\0') char r[10] = {'b','a','c','\0'}; // string — declarare si initializare #include <string> string str = "informatica"; string str2(5, 'a'); // "aaaaa" — 5 de 'a' string str3(str, 2, 4); // "form" — substr din pozitia 2, lung 4
string (C++) NU este inclusă în programa oficială de bacalaureat!
La examen folosiți exclusiv char[] și funcțiile din <cstring> (strlen, strcpy, strcat, strcmp etc.).
Utilizarea clasei string la BAC 2024+ poate atrage depunctare sau refuz de corectare pe anumite subiecte.
Secțiunea despre string de mai jos este utilă pentru concursuri sau facultate.
Funcţii pentru caractere — <cctype>
La BAC, foarte des trebuie să verificăm: “e literă? e cifră? e spaţiu?” sau să convertăm litere mari în mici. Biblioteca <cctype> oferă funcţii gata făcute pentru asta. În loc să compari cu coduri ASCII direct, poţi folosi aceste funcţii clare.
✅ Funcţii de verificare (returnează 0 sau non-zero)
| Funcţie | Returnează adevărat când... | Exemplu adevărat | Exemplu fals |
|---|---|---|---|
isalpha(c) | c este literă (A-Z sau a-z) | isalpha('A') | isalpha('3') |
isdigit(c) | c este cifră (0-9) | isdigit('7') | isdigit('a') |
isalnum(c) | c este literă SAU cifră | isalnum('a') | isalnum('!') |
isupper(c) | c este literă MARE (A-Z) | isupper('A') | isupper('a') |
islower(c) | c este literă MICĂ (a-z) | islower('a') | islower('A') |
isspace(c) | c este spaţiu, tab, newline etc. | isspace(' ') | isspace('a') |
ispunct(c) | c este semn de punctuaţie | ispunct('.') | ispunct('a') |
isprint(c) | c este caracter afişabil | isprint('A') | isprint('\0') |
🔄 Funcţii de conversie (returnează char convertit)
| Funcţie | Descriere | Exemplu | Rezultat |
|---|---|---|---|
toupper(c) | Convertşte litera mică în MARE. Dacă c nu e literă, returnează c neschimbat. | toupper('a') | 'A' |
tolower(c) | Convertşte litera MARE în mică. Dacă c nu e literă, returnează c neschimbat. | tolower('A') | 'a' |
tolower(c) echivalent cu c + 32 (dacă c este literă mare). toupper(c) = c - 32 (dacă c este literă mică). Funcţiile din <cctype> sunt mai sigure — nu necesită verificarea tipului!
Exemple practice
#include <cctype> #include <iostream> using namespace std; // 1. Numarare vocale, consoane, cifre, spatii char s[] = "BAC 2024 informatica!"; int vocale=0, cifre=0, spatii=0, consoane=0; for (int i=0; s[i] != '\0'; i++) { char c = tolower(s[i]); // normalizam la minuscule if (c=='a'||c=='e'||c=='i'||c=='o'||c=='u') vocale++; else if (isdigit(s[i])) cifre++; else if (isspace(s[i])) spatii++; else if (isalpha(s[i])) consoane++; } // Rezultat: vocale=8 cifre=4 spatii=2 consoane=6 // 2. Conversie string la MAJUSCULE string str = "informatica"; for (int i=0; i < str.length(); i++) str[i] = toupper(str[i]); // str = "INFORMATICA" // 3. Numarare litere mari vs mici int mari=0, mici=0; char s2[] = "BaC2024"; for (int i=0; s2[i]; i++) { if (isupper(s2[i])) mari++; else if (islower(s2[i])) mici++; } // mari=2 mici=1 // 4. Verificare daca un sir contine doar litere si cifre bool esteAlphanumeric(char s[]) { for (int i=0; s[i]; i++) if (!isalnum(s[i])) return false; return true; }
Funcţii din <cstring> — referinţă completă
📏 Lungime şi copiere
| Funcţie | Descriere | Exemplu | Rezultat |
|---|---|---|---|
strlen(s) | Lungimea şirului (fără '\0') | strlen("abc") | 3 |
strcpy(dest, src) | Copiază src în dest (include '\0') | strcpy(a, "bac") | a = "bac" |
strncpy(dest, src, n) | Copiază maxim n caractere din src | strncpy(a, "bacalaureat", 3) | a = "bac" |
🔗 Concatenare
| Funcţie | Descriere | Exemplu | Rezultat |
|---|---|---|---|
strcat(dest, src) | Concatenează src la finalul dest | strcat(a, "2024") | a+="2024" |
strncat(dest, src, n) | Concatenează maxim n caractere din src | strncat(a, "20245678", 4) | a+="2024" |
⚖️ Comparare
| Funcţie | Returnează | Exemplu | Rezultat |
|---|---|---|---|
strcmp(s1, s2) | <0 dacă s1<s2, 0 dacă egale, >0 dacă s1>s2 | strcmp("ab","ac") | negativ |
strncmp(s1, s2, n) | Compară primele n caractere | strncmp("abc","abx",2) | 0 (egale) |
🔍 Căutare în şir
| Funcţie | Returnează | Exemplu | Rezultat |
|---|---|---|---|
strchr(s, c) | Pointer la prima apariţie a lui c (sau NULL) | strchr("bac",'a') | pointer la 'a' |
strrchr(s, c) | Pointer la ULTIMA apariţie a lui c | strrchr("abcabc",'b') | pointer la al 2-lea 'b' |
strstr(s, sub) | Pointer la prima apariţie a subşirului (sau NULL) | strstr("informatica","atic") | pointer la "atic" |
✂️ Tokenizare şi alte funcţii
| Funcţie | Descriere | Observaţii |
|---|---|---|
strtok(s, delim) | Împarte şirul în cuvânte (tokens) după delimitatori | Modifică şirul original! Apeluri ulterioare: strtok(NULL, delim) |
memset(s, c, n) | Umple n octeţi din s cu valoarea c | memset(s, 0, sizeof(s)) |
Exemple complete
#include <cstring> #include <iostream> using namespace std; // Exemplu 1: strtok — imparte propozitia in cuvinte char prop[] = "Astazi este o zi frumoasa"; char *token = strtok(prop, " "); while (token != NULL) { cout << token << endl; token = strtok(NULL, " "); } // Afiseaza: Astazi / este / o / zi / frumoasa // Exemplu 2: strchr — gaseste prima aparitie char s[] = "bac"; char *p = strchr(s, 'a'); if (p != NULL) cout << "Gasit la pozitia: " << (p - s) << endl; // 1 // Exemplu 3: strstr — verifica aparitia unui cuvant char text[] = "Examenul de informatica este maine"; if (strstr(text, "informatica") != NULL) cout << "Cuvantul a fost gasit!" << endl;
strncpy cu verificare explicită.
Metode ale clasei string (C++)
// Referinta completa metode string string s = "informatica"; // Lungime si acces s.length() // 11 s.size() // 11 (identic cu length()) s.empty() // false s[0] // 'i' s.at(0) // 'i' (cu verificare bounds) s.front() // 'i' (primul caracter) s.back() // 'a' (ultimul caracter) // Subsirul si cautare s.substr(3, 4) // "orma" (de la poz 3, lungime 4) s.find("tica") // 7 (poz prima aparitie) s.find("xyz") // string::npos (nu exista) s.rfind("a") // 10 (ultima aparitie) // Modificare s.replace(0, 4, "XX") // "XXrmatica" (inlocuieste 4 char de la poz 0) s.erase(2, 3) // sterge 3 char de la poz 2 s.insert(2, "XY") // insereaza "XY" la poz 2 s.clear() // golesste sirul // Conversie s.c_str() // const char* (pt functii C) // Verificare existenta if (s.find("info") != string::npos) cout << "Gasit!"; // Concatenare cu += string a = "bac", b = "2024"; a += b; // a = "bac2024" a += '!'; // a = "bac2024!"
Citirea sirurilor de caractere
char s[201]; string str; // cin >> — citeste pana la primul spatiu/newline cin >> s; // "bac" (fara spatii) cin >> str; // identic pentru string // cin.getline — linie intreaga (cu spatii) — char[] cin.getline(s, 201); // citeste maxim 200 caractere + '\0' cin.getline(s, 201, ','); // citeste pana la ',' sau maxim 200 // getline — linie intreaga — string getline(cin, str); // ATENTIE: daca cititi un numar inainte de un sir! int n; cin >> n; cin.ignore(); // consuma newline-ul ramas getline(cin, str); // acum functioneaza corect
cin >> n si apoi un sir cu getline, fara cin.ignore(), getline citeste linia goala ramasa!
Algoritmi clasici pe siruri
1. Verificare palindrom
bool estePalindrom(string s) { int n = s.length(); for (int i=0; i < n/2; i++) if (s[i] != s[n-1-i]) return false; return true; } // "radar" → true | "madam" → true | "bac" → false
2. Verificare anagrama (cu tablou frecvente)
bool esteAnagrama(string a, string b) { if (a.length() != b.length()) return false; int freq[26] = {0}; for (int i=0; i < a.length(); i++) { freq[tolower(a[i]) - 'a']++; freq[tolower(b[i]) - 'a']--; } for (int i=0; i < 26; i++) if (freq[i] != 0) return false; return true; } // "listen" si "silent" → true | "race" si "care" → true
3. Cifru Caesar
string criptCaesar(string s, int k) { k = ((k % 26) + 26) % 26; // k poate fi negativ for (int i=0; i < s.length(); i++) { if (s[i] >= 'a' && s[i] <= 'z') s[i] = 'a' + (s[i]-'a'+k) % 26; else if (s[i] >= 'A' && s[i] <= 'Z') s[i] = 'A' + (s[i]-'A'+k) % 26; } return s; } // decriptare = criptCaesar(s, 26-k) // criptCaesar("abc", 3) → "def"
4. Cel mai lung cuvant din propozitie
string linie, cuvCurent, maxCuv; getline(cin, linie); linie += " "; // adaugam spatiu la final for (int i=0; i < linie.length(); i++) { if (linie[i] != ' ') cuvCurent += linie[i]; else { if (cuvCurent.length() > maxCuv.length()) maxCuv = cuvCurent; cuvCurent = ""; } } cout << maxCuv;
5. Inversarea unui sir (in-place)
void inverseaza(string &s) { int st=0, dr=s.length()-1; while (st < dr) { swap(s[st], s[dr]); st++; dr--; } } // inverseaza("bac") → "cab"
6. Eliminare duplicate consecutive
string elimDup(string s) { string rez = ""; if (s.empty()) return rez; rez += s[0]; for (int i=1; i < s.length(); i++) if (s[i] != s[i-1]) rez += s[i]; return rez; } // "aaabbc" → "abc" | "mississippi" → "misisipi"
7. Numara cuvintele dintr-o propozitie
int nrCuvinte(string s) { int cnt = 0; bool inCuv = false; for (int i=0; i < s.length(); i++) { if (!isspace(s[i])) { if (!inCuv) { cnt++; inCuv=true; } } else inCuv = false; } return cnt; } // "Bac 2024 info" → 3
Conversii numar ↔ sir
#include <cstdlib> // atoi, atof, atol #include <cstdio> // sprintf // C-style: numar → sir cu sprintf char buf[50]; sprintf(buf, "%d", 42); // buf = "42" sprintf(buf, "%.2f", 3.14); // buf = "3.14" sprintf(buf, "%05d", 7); // buf = "00007" // C-style: sir → numar int n = atoi("123"); // 123 double d = atof("3.14"); // 3.14 // Manual: cifre din numar → sir int nr = 12345; char cifre[20]; int len = 0; while (nr > 0) { cifre[len++] = '0' + nr % 10; nr /= 10; } cifre[len] = '\0'; for (int i=0; i < len/2; i++) swap(cifre[i], cifre[len-1-i]); // cifre = "12345" // Manual: sir de cifre → numar char str[] = "12345"; int val = 0; for (int i=0; str[i] != '\0'; i++) val = val * 10 + (str[i] - '0'); // val = 12345
Demo Interactiv — Operatii pe siruri
Experimentează cu operaţiile pe siruri direct în browser!
Exerciţii interactive — testează cunoştinţele
Probleme tip BAC — siruri de caractere
string linie, cuvantCurent, maxCuvant; getline(cin, linie); linie += " "; for (int i=0; i < linie.length(); i++) { if (linie[i] != ' ') cuvantCurent += linie[i]; else { if (cuvantCurent.size() > maxCuvant.size()) maxCuvant = cuvantCurent; cuvantCurent = ""; } } cout << maxCuvant;
string vocale = "aeiou"; for (int i=0; i < s.length(); i++) if (vocale.find(s[i]) != string::npos) s[i] = '*';
char s[501], cuv[50][50]; int nc = 0; cin.getline(s, 501); char *p = strtok(s, " "); while (p != NULL) { strcpy(cuv[nc++], p); p = strtok(NULL, " "); } for (int i=nc-1; i >= 0; i--) cout << cuv[i] << " ";
char a[101], b[101]; cin.getline(a, 101); cin.getline(b, 101); if (strlen(a) != strlen(b)) { cout << "NU"; return 0; } int freq[256] = {0}; for (int i=0; a[i]; i++) freq[(unsigned char)a[i]]++; for (int i=0; b[i]; i++) freq[(unsigned char)b[i]]--; for (int i=0; i < 256; i++) if (freq[i] != 0) { cout << "NU"; return 0; } cout << "DA";
char s[501]; cin.getline(s, 501); int cnt = 0; bool inCuv = false; for (int i=0; s[i]; i++) { if (!isspace(s[i])) { if (!inCuv && isupper(s[i])) cnt++; inCuv = true; } else inCuv = false; } cout << cnt;
auto isPal = [](string w) { for (int i=0; i < w.size()/2; i++) if (w[i] != w[w.size()-1-i]) return false; return true; }; string linie; getline(cin, linie); linie += " "; string cuvant = ""; for (char c : linie) { if (c != ' ') cuvant += c; else { if (!cuvant.empty() && isPal(cuvant)) cout << cuvant << " "; cuvant = ""; } }