Wednesday, January 1st 2020

Stringhe in C

In questa lezione impariamo ad utilizzare le stringhe in C.

Cos’è una stringa

Nei nostri programmi abbiamo spesso parlato di numeri e caratteri, ma mai di stringhe. Una stringa è semplicemente una serie di caratteri uniti fra loro. Quando per esempio utilizziamo printf() per stampare del testo tra doppi apici, stiamo in realtà stampando una stringa.

//CIAO è una stringa
printf("CIAO");

Dato che una stringa è una serie di caratteri la possiamo immaginare come un array. Per rendere noto al computer quando finisce una stringa sarà necessario aggiungere un carattere terminatore di stringa, che in C è \0.

stringa c

Utilizzare una stringa in C

Una piccola premessa: C non è un linguaggio ottimizzato per le stringhe, pertanto lavorarci diventa molto complicato, soprattutto quando dobbiamo gestire l’input dell’utente. Un approccio didattico, a mio parere, è più che sufficiente.

Dato che una stringa in C è a tutti gli effetti un array, dichiareremo un array di char. La dimensione di questo array, per poter salvare una stringa di n caratteri dovrà essere n + 1, questo perché alla fine della stringa sarà necessario inserire il carattere terminatore.

utilizzo di una stringa in c

E’ possibile assegnare un valore iniziale alla stringa senza doverla inserire carattere per carattere: al momento della dichiarazione si utilizzano delle parentesi graffe con al loro interno il contenuto della stringa tra doppi apici. Ovviamente la dimensione dell’array deve essere maggiore o uguale a quella della stringa da inserire.

contenuto di una stringa in c

Per leggere in input una stringa si utilizza scanf() con il carattere speciale %s. Per stamparne una, si userà printf() con lo stesso carattere.

Se però hai bisogno di leggere in input una stringa con degli spazi allora dovrai usare %[^\n]s. Questo carattere di input porta però ad una lettura involontaria del buffer di input, arginabile con l’utilizzo della funzione fflush() con parametro stdin, che svuota il buffer di lettura.

#include <stdio.h>

int main(){

    char str[20];

    //Leggo una stringa senza spazi
    scanf("%s",&str);

    //Stampo una stringa
    printf("%s\n",str);

    //Svuoto il buffer di input, in modo che lo scanf qui sotto non venga eseguito per sbaglio
    fflush(stdin);

    // Leggo una stringa con degli spazi
    scanf("%[^\n]s",&str);

    //Stampo una stringa
    printf("%s\n",str);

    //Sarebbe buona regola chiamare fflush(stdin) ogni volta che viene utilizzata scanf dal momento in cui si utilizza %[^\n]s , per evitare letture involontarie
    fflush(stdin);
return 0;
}

Inserendo per due volte consecutive Nicola Bovolato nel programma precedente ottengo il seguente output:

Nicola
Nicola Bovolato

Funzioni per stringhe

In C è presente la libreria string.h, che contiene delle funzioni fondamentali quando utilizziamo le stringhe. Includere questa libreria nel nostro programma ci rende tutto un po’ più facile.

Tra le funzioni più importanti abbiamo:

  • Comparazione tra due stringhe
  • Lunghezza di una stringa
  • Copiare una stringa
  • Trovare la posizione di un carattere in una stringa

Per comparare due stringhe non possiamo utilizzare l’operatore di uguaglianza == poiché stiamo comparando una serie di elementi e non due elementi singoli. La funzione strcmp() viene in nostro aiuto: essa ritorna 0 se le stringhe inserite come parametri sono uguali.

char stringa[] = {"COMPARAZIONE"};

//Se il risultato di strcmp è uguale a 0 allora le stringhe sono uguali
if( strcmp(stringa, "COMPARAZIONE") == 0) {
    printf("Stringhe uguali!");
}
else{
    printf("Stringhe diverse");
}

Per trovare la lunghezza di una stringa, anziché iterare un array finché non troviamo il carattere \0 potremmo utilizzare strlen(), che data in input una stringa ne ritorna la lunghezza.

char stringa[] = {"UNA STRINGA MOLTO MOLTO LUNGA"};

int lunghezza = strlen(stringa);

printf("La stringa e lunga %d caratteri", lunghezza);

Se abbiamo bisogno di copiare una stringa in un altro array possiamo utilizzare strcpy(), che fa esattamente questo. Il primo parametro è la destinazione mentre il secondo è la stringa da copiare.

char stringa[] = {"DA SPOSTARE"};
char nuova_stringa[50];

//Copio il contenuto di stringa in nuova_stringa
strcpy(nuova_stringa,stringa);
printf("%s",nuova_stringa);

Per trovare la posizione di un carattere all’interno di una stringa abbiamo a disposizione due funzioni diverse: strchr() e strrchr(). Entrambe prendono in input una stringa da analizzare e un carattere da cercare e ne ritornano la posizione. strchr() ritornerà la posizione del primo carattere trovato mentre strrchr() ritornerà l’ultima. Entrambe se non trovano un carattere ritorneranno -1.

char stringa[] = {"TROVA CARATTERE"};

//Trovo la posizione della prima A
int prima = strchr(stringa, 'A');

//Trovo la posizione dell'ultima A
int ultima = strrchr(stringa, 'A');

//Trovo la posizione di un elemento non presente in stringa
int inesistente = strchr(stringa, 'Z');

printf("Posizione della prima a: %d",prima);
printf("Posizione dell' ultima a: %d",ultima);
printf("Posizione della prima z: %d",inesistente);

Programma di esempio

Utilizzando quanto abbiamo imparato scriviamo un programma che ci trova il numero di vocali in un testo inserito in input.

#include <stdio.h>
#include <string.h>

int trova_numero_lettera(char *str,char lettera);

int main(){
	char testo[500];

	printf("Inserisci un testo (max 500 caratteri): \n");
	scanf("%[^\n]s",&testo);

	int numA = trova_numero_lettera(testo,'a') + trova_numero_lettera(testo,'A');
	int numE = trova_numero_lettera(testo,'e') + trova_numero_lettera(testo,'E');
	int numI = trova_numero_lettera(testo,'i') + trova_numero_lettera(testo,'I');
	int numO = trova_numero_lettera(testo,'o') + trova_numero_lettera(testo,'O');
	int numU = trova_numero_lettera(testo,'u') + trova_numero_lettera(testo,'U');
	int tot = numA + numE + numI + numO + numU;


	printf("Quantita vocali: %lf %% \n", (double)tot / strlen(testo) * 100);
	printf("Numero di A: %d\n",numA);
	printf("Numero di E: %d\n",numE);
	printf("Numero di I: %d\n",numI);
	printf("Numero di O: %d\n",numO);
	printf("Numero di U: %d\n",numU);

	return 0;

}

int trova_numero_lettera(char *str,char lettera){

	int i;
	int lunghezza = strlen(str);
	int numero_lettere = 0;

	for(i = 0; i < lunghezza; i++){
		if(str[i] == lettera){
			numero_lettere++;
		}
	}

	return numero_lettere;

}

Inserendo il testo “Impariamo ad usare le stringhe in C” otteniamo il seguente risultato:

Quantita vocali: 37.14 %
Numero di A: 4
Numero di E: 3
Numero di I: 4
Numero di O: 1
Numero di U: 1