Stringhe in C++
Una stringa in informatica è una sequenza di caratteri alfanumerici, che
possono essere lettere, numeri e caratteri speciali. In linguaggio C standard,
una stringa è rappresentata da un array di caratteri.
In C++, una stringa
è invece un oggetto istanziato da una classe <string>,
dotata di attributi e metodi allo stesso modo in cui viene concepita in
linguaggio Java.
Le stringhe sono più comunemente usate nei programmi in cui abbiamo bisogno di lavorare con i testi. A differenza dei numeri, sui quali possono essere eseguite operazioni aritmetiche, sulle stringhe in C/C++ vengono eseguiti altri tipi di operazioni come la concatenazione l’inversione ed il passaggio di una stringa ad una funzione.
Dichiarazione di stringhe
Una possibile dichiarazione con inizializzazione di stringa è la seguente:
string s1 = "Questa è una stringa ";
oppure
string s2 (" in C++");
Un programma completo che comprenda queste dichiarazioni è il seguente
#include<iostream>
#include<string>
using namespace std;
main(){
string s1 = "Questa è una stringa";
string s2 ("in C++");
cout<<s1<<endl;
cout<<s2;
}//fine main
il file contenente queste istruzioni deve avere estensione .cpp, dato che il C standard (che ha files con estensione .c) non supporta la classe <string>.
Se volessimo usare il linguaggio C standard e quindi considerare le stringhe degli array di caratteri, invece che oggetti, le dichiarazioni potrebbero essere le seguenti:
char s1 [] = " Questa"; oppure
char s1 [7] = " Questa"; oppure
char s1 [] = { 'Q','u','e','s','t','a','\0' }; oppure
char s1 [7] = { 'Q','u','e','s','t','a','\0' };
Nel secondo caso dobbiamo anche aggiungere un carattere terminatore nell'array,
la lunghezza dell'array è dunque maggiore di uno della lunghezza della stringa.
Nello stile C il carattere '\0' deve essere aggiunto
alla fine della stringa per indicare che questa è terminata.
Questa caratteristica non esiste negli oggetti stringa del C++.
Il programma con estensione .c che verifica queste funzionalità è il seguente:
#include<stdio.h>
main(){
char s1[7] = {'Q','u','e','s','t','a','\0'};
char s2[]="è una stringa in C++";
printf("%s %s",s1,s2);
}//fine main
Input di stringhe
Per eseguire l'input da tastiera, generalmente utilizziamo la parola chiave cin insieme all'operatore di estrazione (>>). Per impostazione predefinita, l'operatore di estrazione considera lo spazio bianco (come spazio, tabulazione o nuova riga) come carattere di chiusura. Supponiamo quindi che l'utente immetta "Questa è una stringa" come input. In tal caso, solo "Questa" verrà considerato input e il resto verrebbe ignorato.
#include<iostream>
#include<string>
using namespace std;
main(){
string s;
cout<<"ins.stringa:";cin>>s;
cout<<s;
}//fine main
Se introduciamo "questa è una stringa" verrebbe acquisita solo la parola "questa".
L'operazione di lettura teminerà al primo "spazio bianco" incontrato,gli
altri caratteri resteranno nello stream di ingresso. Non è possibile,pertanto,acquisire
in questo modo frasi composte da più parole. I caratteri acquisiti sono
memorizzati nel vettore specificato ( a partire dall'elemento con indice
0) e il carattere "spazio bianco" è automaticamente sostituito con il carattere
terminatore di stringa '\0'.
Si rammenta che i caratteri che rimangono memorizzati nello stream di ingresso
saranno interpretati come dati al momento della successiva acquisizione.
Occorre tenere conto, se si vogliono evitare comportamenti indesiderati
dal programma, che per acquisire anche gli "spazi bianchi" di una stringa
(tranne il ritorno a capo, new-line)ovvero stringhe formate da più parole,
si può impiegare il metodo getline() di cin:
cin.getline(s 20);
La stringa è automaticamente terminata con il carattere '\0' quando preme invio oppure quando il numero di caratteri digitati raggiunge il numero specificato tra parentesi meno 1; in questo modo si garantisce che la stringa acquisita non superi la dimensione massima del vettore desinato a contenerla.
Per evitare comportamenti anormali,prima di impiegare getline() è bene eliminare dallo stream di ingresso ogni possibile carattere residuo, in particolare quelli di ritorno a capo(new-line o '\n'). per farlo si puo impiegare il metodo ignore():
cin.ignore(); // elimina l'ultimo carattere presente nello stream di ingresso
In questo modo, dallo stream di ingresso viene eliminato solo un carattere,
che solitamente è proprio un new-line.
Se nello stream sono presenti più caratteri, per "ignorarli" si può usare
ignore() in questo modo:
cin.ignore(10000, '\n'); // elimina fino ad un massimo di 10000 caratteri
In questo caso, saranno ignorati 10000 caratteri o perlomeno tutti quelli fino al carattere '\n' (new-line) compreso.
Se invece vogliamo evitare un dimensionamento preventivo ed ovviare a queste limitazioni dell'operatore di estrazione, possiamo usare l'istruzione getline(cin,s) con le seguenti modalità:
#include<iostream>
#include<string>
using namespace std;
main(){
string s;
cout<<"ins.stringa:";
getline(cin,s);
cout<<s;
}//fine main
oppure la funzione cin.get() secondo la sintassi cin.get(s, 20).
Per la scrittura di stringhe solitamente si usa l'oggetto cout:
cout << s;
Allo stream di uscita standard saranno automaticamente inviati, in sequenza, tutti i caratteri contenuti nel vettore nome, escluso il carattere terminatore.
Accesso agli elementi di una stringa
Essendo stata definita come un array di caratteri, si può accedere agli
elementi di una stringa in C/C++ allo stesso modo in cui si accede agli
elementi di un vettore (array monodimensionale) di numeri.
In particolare si può eseguire la scansione dei caratteri della stringa
attraverso un ciclo for() tenendo conto della lunghezza
della stringa che nella libreria
#include<iostream>
#include<string>
using namespace std;
main(){
string s="Lambda";
for(int i=0;i<s.size();i++)cout<<" "<<s[i];
cout<<endl<<s[2];
} //fine main
In C-standard la libreria <string.h> ottiene tale valore attraverso la funzione strlen():
#include <stdio.h>
#include <string.h>
main(){
char s[]="Lambda";
for(int i=0;i<strlen(s);i++)printf(" %c",s[i]);
printf("\n%c",s[2]);
}
Nell'esempio, l'output dell'elemento s[2] determina la rappresentazione del terzo carattere della stringa (che ha indice 2).
In C++ attraverso la classe string è possibile usare una notazione che non preveda l'uso delle parentesi quadra, questo attraverso l'uso del metodo at() qui sotto illustrato.
#include<iostream>
#include<string>
using namespace std;
main(){
string s="Lambda";
for(int i=0;i<s.size();i++)cout<<" "<<s.at(i);
cout<<endl<<s.at(2);
} //fine main
Concatenazione di stringhe
La concatenazione di stringhe in C++ risulta di facile applicazione grazie all'operatore +.
#include<iostream>
#include<string>
using namespace std;
main(){
string s1="Alfa";
string s2="Beta";
s1=s1+s2;
cout<<s1;//-->AlfaBeta
} //fine main
oppure tramite il metodo append() applicabile attraverso la sintassi: s1=s1.append(s2);
Questa operazione om C-standard viene eseguita tramite la libreria string.h attraverso la funzione strcat().
#include <stdio.h>
#include <string.h>
main(){
char s1[]="Alfa";
char s2[]="Beta";
strcat(s1, s2);
printf("%s", s1);
}
Il risultato è quello di concatenare la stringa s2 alla fine della stringa s1.
Comparazione di stringhe
Il confronto tra stringhe può essere eseguito molto comodamente tramite gli operatori relazionali == oppure !=.
#include<iostream>
#include<string>
using namespace std;
main(){
string s1="Alfa";
string s2="Beta";
if(s1==s2)cout<<"uguali";
else cout<<"disuguali";
} //fine main
La classe string mette poi a disposizione un opportuno metodo compare() che restituisce 0 se le due stringhe sono identiche.
#include<iostream>
#include<string>
using namespace std;
main(){
string s1="Alfa";
string s2="Beta";
if(s1.compare(s2)==0)cout<<"uguali";
else cout<<"disuguali";
} //fine main
In C-standard, con la libreria string.h, esiste una funzione analoga chiamata strcmp() con le stesse regole.
#include <stdio.h>
#include <string.h>
main(){
%nbsp;char s1[]="Alfa";
%nbsp;char s2[]="Beta";
%nbsp;if(strcmp(s1, s2)==0)printf("uguali");
%nbsp;else printf("disuguali");
}
Copiare una stringa in un'altra
Per eseguire questo tipo di operazione è sufficiente usare l'operatore
di assegnamento =.
Tuttavia, il metodo più appropriato risulta essere assign().
#include<iostream>
#include<string>
using namespace std;
main(){
string s1="Alfa";
string s2="Beta";
s1.assign(s2);// s1=s2
cout<<s1<<" "<<s2;
} //fine main
Il C-standard, esegue questo tipo di operazione esclusivamente con la funzione strcpy() che ha l'effetto di copiare la stringa sorgente nella stringa destinazione:
#include <stdio.h>
#include <string.h>
main(){
char s1[]="Alfa";
char s2[]="Beta";
strcpy(s1, s2);
printf("%s %s",s1,s2);
}
Ottenere una sottostringa
Il metodo substr() viene usato per ottenere una sottostringa ( una nuova stringa) facendo una copia totale o parziale di una stringa iniziale. La sintassi è:
s.substr(pos,lg);
dove pos è la posizione iniziale della copia e lg la lunghezza in caratteri del testo da copiare.
#include<iostream>
#include<string>
using namespace std;
main(){
string s = "AlfaBeta";
string sub;
sub = s.substr(0,3);
cout<<sub;// --->Alf
}
Copia di una sottostringa
Supponiamo che src e des
siano due oggetti stringa, lg è la lunghezza della
sottostringa.
Vogliamo copiare la stringa src (sorgente) nell'oggetto
stringa des (destinazione), quindi la sintassi del comando
potrà essere:
src.copy(des,lg);
src.copy(des,lg,pos);
dove pos è la posizione da cui si inizia a copiare la stringa sorgente src.
#include<iostream>
#include<string>
using namespace std;
main(){
string src = "Alfa Beta Gammma";
char des[13] ;
src.copy(des,6,4);
des[5] ='\0';
cout<<des;//-->Beta
} //fine main
Ricerca di una stringa
Il metodo find() viene usato per cercare una specifica sottostringa all'interno di una stringa. Viene usato con la sintassi
s1.find(s2)
restituisce la posizione della sottostringa s2 all'interno della stringa s1 ad esempio:
#include<iostream>
#include<string>
using namespace std;
main(){
string s= "Mangiare la mela fa bene alla salute";
cout<< s.find("mela");//-->12
} //fine main
ma può anche essere usata con sintassi s1.find(s2,pos) dove pos è la posizione di partenza da cui iniziare a cercare.
Inserimento di una stringa
Questo metodo è in grado di inserire una stringa in una sottostringa, prima del carattere indicato dalla posizione pos.
s1.insert(pos,s2);
dove s1 è la stringa di destinazione ed s2 la stringa da inserire.
#include<iostream>
#include<string>
using namespace std;
main(){
string s= "alfa beta delta";
s.insert(5,"gamma ");
cout<<s;//--> alfa beta gamma delta
} //fine main
Cancellazione di una sottostringa
Per cancellare parti di una stringa si usa il metodo erase() con sintassi:
str.erase(pos,lg);
#include<iostream>
#include<string>
using namespace std;
main(){
string s= "alfa omega gamma";
s.erase(5,6);
cout<<s;//-->alfa gamma
} //fine main
Sostituzione di una sottostringa
La funzione replace() ha lo scopo di sostituire uno o più caratteri all'interno di una stringa con un'altra sottostringa.
Considerando due stringhe str e sub la sintassi è:
str.replace(pos,lg,sub,[subpos],[sublg]);
str : è un oggetto stringa,
sub : è un oggetto stringa il cui valore (o parte
di tale valore) deve essere copiato nella stringa str.
pos : definisce la posizione del carattere da sostituire.
lg : numero di caratteri da sostituire (eliminare)
nella stringa str.
subpos : definisce la posizione del primo carattere
della sottostringa sub che deve essere copiato nella
stringa str.
sublg : Numero di caratteri dell'oggetto stringa
sub da copiare nella stringa str.
In questo primo esempio mostra come sostituire una stringa data utilizzando come parametri la posizione pos e la lunghezza lg.
#include<iostream>
using namespace std;
main(){
string str ="alpha beta gamma delta";
string sub= "12345";
cout <<str<<'\n';
str.replace(11,sub.size(),sub);
cout<<str<<'\n';
}
Output:
alpha beta gamma delta
alpha beta 12345 delta
Questo secondo esempio mostra come sostituire un'occorrenza nella stringa str usando solo una parte della sottostringa sub, usando la posizione (subpos) e lunghezza (sublg) della sottostringa sub da inserire nella stringa str.
#include<iostream>
using namespace std;
main(){
string str ="mangio una arancia rossa";
string sub= "questa è una mela verde";
cout <<str<<'\n';
str.replace(11,7,sub,13,4);
cout<<str<<'\n';
}
Output:
mangio una arancia rossa
mangio una mela rossa
Negli esercizi eseguiti si fanno ulteriori esempi di utilizzo di questi metodi.