Riepilogo
Il testo è il dato più frequente di un programma: nomi, messaggi, righe di un file, comandi di un utente. Questa lezione lo tratta come ciò che è per il C++, una sequenza di caratteri con operazioni proprie. Presenta std::string, che si crea, si concatena, si confronta e si scorre come un vettore di char con mestiere di testo; le sue operazioni di ricerca e di estrazione (find, substr, starts_with, contains) e il valore std::string::npos, con cui find dice di non aver trovato nulla; std::string_view, la vista che osserva un testo senza copiarlo, e la condizione da cui dipende: che il testo osservato continui a esistere. Chiudono la lezione le stringhe C, per leggere codice altrui, e l’ordine in cui il C++ confronta e ordina le parole.
Obiettivi di apprendimento
- Usare le operazioni di
std::string(size,+,find,substr,starts_with,contains) per risolvere problemi di testo. - Interpretare il risultato di
finde confrontarlo constd::string::npos, e prevedere che cosa accade se lo si tratta come un numero qualsiasi. - Ricevere testo in una funzione come
std::string_viewe spiegare con un esempio perché una vista non deve sopravvivere alla stringa che osserva. - Leggere codice con stringhe C e spiegarne le differenze rispetto a
std::string: il terminatore nullo, la dimensione fissa e la somma di due letterali, che non compila.
La stringa std::string
Creare, concatenare, scorrere
La lezione Caratteri, booleani, conversioni e costanti ha presentato il carattere, char, come un numero piccolo che una tabella converte in lettera. Un testo è una successione di caratteri; se è così, può essere conservato in uno std::vector<char>, e ciò che la lezione Vettori ha insegnato sulle sequenze varrebbe per esso. Ora, al testo si chiedono operazioni che a una sequenza qualsiasi non si chiedono: attaccargli un altro testo, cercarvi una parola, estrarne un pezzo, scriverlo in una volta sola. Ne segue un tipo proprio, la stringa, std::string, dell’header <string>: un vettore di char con mestiere di testo.
#include <format>#include <print>#include <string>int main(){ const std::string first{"Ada"}; std::string greeting{"Ciao, " + first}; greeting += '.'; std::println("{} ({} caratteri)", greeting, greeting.size()); std::println("Primo «{}», ultimo «{}»", greeting[0], greeting.back()); int spaces{0}; for (const char c : greeting) { if (c == ' ') { ++spaces; } } std::println("Spazi: {}", spaces); const std::string code{std::format("{}-{:03}", "MAT", 7)}; std::println("{} {}", code, code == "MAT-007");}Ciao, Ada. (10 caratteri)Primo «C», ultimo «.»Spazi: 1MAT-007 trueLa riga 7 crea una stringa a partire da un letterale. La 8 la concatena: l’operatore + tra una stringa e un letterale produce una stringa nuova con i caratteri di entrambi, uno dopo l’altro. La 9 aggiunge un carattere alla fine con +=, che ammette anche una stringa o un letterale. Il resto è ciò che già si sapeva dei vettori: size() conta i caratteri (10, perché anche la virgola, lo spazio e il punto lo sono), greeting[0] è il primo e back() l’ultimo, e il ciclo delle righe da 13 a 17 scorre la stringa carattere per carattere con la forma per intervallo della lezione Cicli. Come il vettore, una stringa ammette inoltre push_back, pop_back e empty, e la libreria di GCC 15, quando non si ottimizza, controlla i suoi indici con operator[] (con l’ottimizzazione, quel controllo scompare).
Le ultime due righe mantengono ciò che aveva annunciato la lezione Progettare con le funzioni. std::format, di <format>, riceve gli stessi segnaposto di std::println, con le stesse specifiche di formato ({:03} riempie con zeri fino a tre cifre), ma invece di scrivere il risultato lo restituisce come stringa: è il modo di costruire un testo che poi si conserva, si confronta o si passa a una funzione. E == confronta due stringhe per il loro contenuto: sono uguali se hanno la stessa dimensione e gli stessi caratteri nello stesso ordine. Pertanto code == "MAT-007" è true, benché il testo di sinistra sia stato costruito a pezzi e quello di destra sia un letterale.
Confrontare
Oltre a == e !=, le stringhe ammettono <, <=, > e >=, che le confrontano in ordine lessicografico, quello del dizionario: si percorrono le due in parallelo, e nella prima posizione in cui differiscono decide il carattere minore; se una si esaurisce prima senza alcuna differenza, la più corta è la minore. Così la stringa «casa» è minore di «cosa», perché 'a' < 'o' nella seconda posizione, e «mare» è minore di «marea», perché la prima è un prefisso della seconda. Gli operatori confrontano stringhe: tra due letterali scritti tra virgolette confrontano un’altra cosa, perché un letterale non è uno std::string ma un array, come si vedrà nella sezione sulle stringhe C. Quale carattere sia «minore» lo decide il suo codice, non l’alfabeto; l’ultima sezione della lezione mostra che cosa ne segue.
Caricamento del contenuto…