Șiruri de caractere
Tabloul de caractere, terminatorul nul, citirea unei linii întregi și de ce nu folosim tipul string la bac.
Ce este un șir
Un șir de caractere este un tablou de char. Sfârșitul textului e marcat de un caracter special, '\0', numit terminator nul.
char s[101];Declarația face loc pentru 101 caractere, adică un text de cel mult 100 de caractere plus terminatorul.
De aici regula de dimensionare: dacă enunțul spune „cel mult 200 de caractere", declari char s[201].
Terminatorul nul
char s[10] = "abc";În memorie se află a, b, c, \0, iar restul nu contează.
Terminatorul nu se vede și nu intră în lungime, dar fără el nimic nu funcționează. Toate funcțiile de lucru cu șiruri se opresc la el. Un șir fără terminator e citit mai departe, în memoria de după, până se dă peste un zero întâmplător.
De aceea, dacă construiești un șir caracter cu caracter, trebuie să-l închizi tu:
char rez[101];
int k = 0;
for (int i = 0; s[i] != '\0'; i++)
if (isalpha(s[i]))
rez[k++] = s[i];
rez[k] = '\0'; // obligatoriuUltima linie se uită des. Îți dai seama după simptom: se afișează textul corect, urmat de caractere fără sens.
De ce nu string
C++ are un tip string, mult mai comod. Nu este în programa de bacalaureat, iar o soluție care îl folosește nu primește punctaj, la fel ca una cu vector, sort sau map. Pe această platformă, un item în care apare string primește direct 0.
La examen scrii în C/C++, dar din biblioteca standard C++ folosești doar cin/cout și fișierele. Rămân deci tablourile de char și funcțiile din <cstring>.
Citirea
Un singur cuvânt
char s[101];
cin >> s;Citirea se oprește la primul spațiu. Observă că nu se scrie &s, pentru că numele tabloului este deja adresa lui.
O linie întreagă
cin.getline(s, 101);Al doilea argument este dimensiunea tabloului, nu lungimea textului. Se citește tot până la linie nouă, inclusiv spațiile.
Capcana clasică: după un cin >> n, în flux rămâne caracterul de linie nouă. getline îl găsește imediat și întoarce un șir gol.
int n;
cin >> n;
cin.get(); // consumă linia nouă rămasă
cin.getline(s, 101);Atenție: cin.getline(s, 101) este forma permisă. Forma getline(cin, s) are nevoie de tipul string și nu este acceptată.
Din fișier
Se face la fel, cu fin în loc de cin:
ifstream fin("date.in");
fin.getline(s, 101);Parcurgerea
Ai două forme echivalente:
for (int i = 0; s[i] != '\0'; i++)
// prelucrez s[i]int n = strlen(s);
for (int i = 0; i < n; i++)
// prelucrez s[i]A doua e mai bună când ai oricum nevoie de lungime. Calculează strlen o singură dată, înaintea buclei. Dacă scrii așa:
for (int i = 0; i < strlen(s); i++) // lentlungimea se recalculează la fiecare pas, iar pentru asta se parcurge tot șirul. La un text lung, o parcurgere simplă devine pătratică.
Indicii pornesc de la 0. La șiruri nu are rost convenția de la 1. Toate funcțiile din bibliotecă lucrează de la 0, iar dacă amesteci cele două convenții apar erori.
Afișarea
cout << s; // tot șirul, până la '\0'
cout << s[0]; // primul caracterUn exemplu complet
Se citește o linie de text. Să se afișeze câte litere mari conține.
#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
char s[256];
int main() {
cin.getline(s, 256);
int cate = 0;
int n = strlen(s);
for (int i = 0; i < n; i++)
if (isupper(s[i]))
cate++;
cout << cate;
return 0;
}Modificarea pe loc
Un șir îl poți modifica direct, caracter cu caracter:
for (int i = 0; s[i] != '\0'; i++)
s[i] = toupper(s[i]);Dacă vrei să ștergi caractere, folosește tiparul cu doi indici de la vectori, unul care citește și unul care scrie:
int k = 0;
for (int i = 0; s[i] != '\0'; i++)
if (s[i] != ' ')
s[k++] = s[i];
s[k] = '\0';Codul elimină toate spațiile într-o singură parcurgere, fără niciun tablou suplimentar.
De reținut
- Un șir este un tablou de
charîncheiat cu'\0'. - Declară cu un loc mai mult decât lungimea maximă din enunț.
- Când construiești un șir, pune tu terminatorul la final.
cin >> sia un cuvânt,cin.getline(s, dim)ia o linie. Dupăcin >> n, consumă linia nouă rămasă.- Nu folosi
string. Nu e în programă și se punctează cu zero. - Calculează
strleno singură dată, în afara buclei.