edutecnica

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 può essere restituita indifferentemente dai due metodi length() oppure size().

#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.