MORENO SARDELLA · CORSO BASE
← Tutte le lezioni
Lezione 4

LE STRINGHE

Le parole, in un programma, sono sequenze di caratteri. Il C++ offre due modi per gestirle: le C-stringhe (più "vicine alla macchina") e la classe string (più comoda). Vediamo entrambe e cosa succede in memoria.

01
Due strade

C-stringhe vs string

C-stringa

array di char

È un array di caratteri terminato dal carattere speciale '\0'. Dimensione fissa, gestione manuale.

char nome[10] = "Ciao";

string

classe della libreria

Un oggetto che gestisce da solo la memoria e la lunghezza. Si concatena con +, si confronta con ==.

#include <string> string nome = "Ciao";
02
In memoria

Il terminatore \0

Una C-stringa occupa in RAM una cella per ogni carattere, più una cella finale che contiene '\0' (il carattere con codice 0). Serve a segnalare "qui la stringa finisce": senza, il programma non saprebbe dove fermarsi.

C I A O \0 ? 0 1 2 3 4 5 inutilizzata
"Ciao" occupa 5 celle: 4 lettere + il terminatore '\0' in posizione 4.
lunghezza.cpp
// la lunghezza si calcola contando fino al terminatore
char s[] = "Ciao";
int len = 0;
while (s[len] != '\0') len++;
cout << len;          // stampa 4
03
Funzioni di libreria

strcpy e strcmp

La libreria <cstring> mette a disposizione funzioni per lavorare sulle C-stringhe. Le due più importanti sono strcpy (copia) e strcmp (confronto).

strcpy · copiare

strcpy(dest, sorg) copia tutti i caratteri di sorg dentro dest, terminatore compreso. Attenzione: dest deve essere abbastanza grande.

sorg H I \0 dest H I \0 ogni cella viene copiata, anche il terminatore
strcpy ricopia carattere per carattere, fino al '\0' incluso.
strcpy.cpp
#include <cstring>
char sorg[] = "Hi";
char dest[10];
strcpy(dest, sorg);     // dest contiene "Hi"
cout << dest;

strcmp · confrontare

strcmp(a, b) confronta due C-stringhe e restituisce 0 se sono uguali, un numero negativo se a viene prima in ordine alfabetico, positivo se viene dopo. Non si possono confrontare con ==!

strcmp.cpp
#include <cstring>
char a[] = "mela", b[] = "pera";
if (strcmp(a, b) == 0) cout << "uguali";
else if (strcmp(a, b) < 0) cout << "a viene prima";
else cout << "b viene prima";
Con la classe string è tutto più semplice: if (a == b) per confrontare, a + b per concatenare, a.length() per la lunghezza. Niente '\0' da gestire a mano.
string.cpp
#include <string>
string nome, cognome;
cout << "Nome e cognome: ";
cin >> nome >> cognome;
string completo = cognome + " " + nome;
cout << completo << " (" << completo.length() << " caratteri)";
04
Esercizi

Gli esercizi

Gli esercizi base lavorano sulle C-stringhe (con il terminatore da gestire a mano); quelli avanzati usano la classe string.

C-stringhe — basescarica ↓
Stringhe — avanzatiscarica ↓
Soluzioni · C-stringhe base
1 — Leggi e stampa char s[50]; cin >> s; for (int i = 0; s[i] != '\0'; i++) cout << s[i];
2 — Lunghezza int len = 0; while (s[len] != '\0') len++; cout << len;
3 — Conta vocali // #include <cctype> int v = 0; for (int i = 0; s[i] != '\0'; i++) { char c = tolower(s[i]); if (c=='a'||c=='e'||c=='i'||c=='o'||c=='u') v++; }
4 — Copia a mano char dest[50]; int i = 0; while (s[i] != '\0') { dest[i] = s[i]; i++; } dest[i] = '\0'; // copia anche il terminatore
5 — Copia con strcpy // #include <cstring> char dest[50]; strcpy(dest, s); cout << dest;
6 — Confronto int r = strcmp(a, b); if (r == 0) cout << "uguali"; else if (r < 0) cout << "a viene prima"; else cout << "b viene prima";
7 — Conta un carattere char ch; cin >> ch; int c = 0; for (int i = 0; s[i] != '\0'; i++) if (s[i] == ch) c++;
8 — Tutto maiuscolo for (int i = 0; s[i] != '\0'; i++) s[i] = toupper(s[i]); cout << s;
9 — Inverti int n = 0; while (s[n] != '\0') n++; for (int i = 0; i < n/2; i++) { char t=s[i]; s[i]=s[n-1-i]; s[n-1-i]=t; } cout << s;
10 — Palindroma int n = 0; while (s[n] != '\0') n++; bool pal = true; for (int i = 0; i < n/2; i++) if (s[i] != s[n-1-i]) pal = false; cout << (pal ? "palindroma" : "non palindroma");
Soluzioni · Stringhe avanzati
1 — Leggi una frase string s; getline(cin, s); cout << s << " (" << s.length() << " caratteri)";
2 — Conta le parole int parole = 0; bool dentro = false; for (char c : s) { if (c != ' ') { if (!dentro) { parole++; dentro = true; } } else dentro = false; }
3 — Cerca una sottostringa int conta = 0; size_t pos = s.find(parola); while (pos != string::npos) { conta++; pos = s.find(parola, pos + 1); }
4 — Sostituisci un carattere for (int i = 0; i < s.length(); i++) if (s[i] == vecchio) s[i] = nuovo;
5 — Nome completo string completo = cognome + " " + nome;
6 — Palindroma // ignora maiuscole/spazi string t; for (char c : s) if (c != ' ') t += tolower(c); bool pal = true; for (int i = 0; i < t.length()/2; i++) if (t[i] != t[t.length()-1-i]) pal = false;
7 — Vocali e consonanti int v=0, c=0; for (char ch : s) { ch = tolower(ch); if (isalpha(ch)) { if (ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u') v++; else c++; } }
8 — Maiuscolo e minuscolo string maiusc = s, minusc = s; for (int i = 0; i < s.length(); i++) { maiusc[i]=toupper(s[i]); minusc[i]=tolower(s[i]); }
9 — Dominio dell'email int pos = email.find('@'); string dominio = email.substr(pos + 1); cout << dominio;
10 — Frase al contrario // #include <sstream> stringstream ss(s); string parola, ris = ""; while (ss >> parola) ris = parola + " " + ris; cout << ris;