
In questa puntata del corso del linguaggio C con il Raspberry PI (per le puntate precedenti consulta il seguente link) affrontiamo un tema molto importante, quello della gestione delle stringhe. Si tratta di una prerogativa comune a tutti i linguaggi di programmazione esistenti, ma quella del C è approcciata in maniera leggermente diversa, più a basso livello (verso la macchina), se vogliamo. Esempi, prove esperimenti e considerazioni per comprendere a fondo, e in maniera indolore, questo importante tassello della programmazione.
Introduzione
Normalmente, una stringa è un insieme, o sequenza di caratteri, rappresentata come costante o memorizzata in una variabile. Definita come costante, essa è racchiusa tra doppi apici, i quali non fanno parte della stringa stessa. Ad esempio: "Hello world" è una stringa composta da 11 caratteri. Il carattere "spazio" fa parte integrante di essa. I caratteri che la compongono fanno parte di un alfabeto preesistente come, ad esempio, il codice Ascii. Il numero di caratteri che compone una stringa rappresenta la sua lunghezza e ovviamente non può essere negativa. Può essere anche pari a zero quando non contiene alcun carattere (stringa nulla). In molti linguaggi di programmazione la stringa è dichiarata come un tipo di dato presente nella sintassi intrinseca. In linguaggio C il discorso è leggermente diverso e lo vedremo nei paragrafi a seguire.
Lo scopo delle stringhe è quello di memorizzare, al loro interno, sequenze di caratteri per poi riutilizzarle all'occorrenza. In esse si possono immagazzinare:
- Nominativi;
- Titoli delle applicazioni;
- Le etichette dei pulsanti;
- Parole per poi elaborarle;
- Messaggi criptati e in chiaro;
- e tanto altro ancora...
Le stringhe nel linguaggio C
Nel linguaggio C, una stringa è definita come un array di caratteri. Non esiste, pertanto, una parola chiave "string" per crearla, come avviene per altre tipologie di ambienti di programmazione. Il suo stanziamento in memoria avviene in più modalità, quindi, normalmente come abbiamo visto nelle puntate precedenti. Il seguente esempio:
char Nome[10];
definisce in memoria un insieme di 10 caratteri, un array (come approfondito in questo articolo) che "prenota" dieci celle da riempire in futuro. Ogni cella è numerata, in questo caso, da 0 a 9, come si evince dalla figura 1.
In qualche modo il linguaggio deve pur conoscere dove termina una stringa, altrimenti le elaborazioni su essa non avrebbero mai fine e le relative visualizzazioni darebbero risultati inaspettati. Il C considera terminata una stringa quando incontra un carattere NULL, definita come carattere '\0' (apice singola perché si tratta di un solo carattere). Senza di esso la lunghezza della stringa potrebbe essere molto alta. Adesso, per inserire i caratteri nell'array, in modo che esso diventi una stringa, vi sono diverse possibilità.
Memorizzazione della stringa per singolo carattere
Questo metodo, un po' scomodo, prevede l'inserimento di ogni carattere della stringa in ciascuna cella dell'array. La cosa importante è quella di prevedere sempre il carattere di terminazione della stringa, onde prevenire effetti spiacevoli, ai fini del programma, come visibile in figura 2. Il seguente listato svolge proprio tale compito:
#include "stdio.h" int main() { char Nome[10]; Nome[0]='G'; Nome[1]='i'; Nome[2]='o'; Nome[3]='v'; Nome[4]='a'; Nome[5]='n'; Nome[6]='n'; Nome[7]='i'; Nome[8]='\0'; printf("%s\n",Nome); }
In questo modo, manualmente, abbiamo inserito i caratteri facenti parte del nome "Giovanni" all'interno dell'array. Non è necessario rispettare strettamente l'ordine degli statement, l'importante è allocare i caratteri nel posto giusto. Pertanto, il seguente codice è equivalente:
#include "stdio.h" int main() { char Nome[10]; Nome[6]='n'; Nome[0]='G'; Nome[2]='o'; Nome[5]='n'; Nome[4]='a'; Nome[7]='i'; Nome[8]='\0'; Nome[1]='i'; Nome[3]='v'; printf("%s\n",Nome); }
La funzione printf la conosciamo già. La stringa di formattazione "%s" fa capire alla funzione che essa deve stampare il contenuto dell'array "Nome" in formato stringa, ossia deve visualizzare, ad uno ad uno, tutti i caratteri in essa presenti, fino al segnale di terminazione stringa ('\0').
Assegnazione diretta
E' possibile memorizzare direttamente la stringa all'inizio del programma, nella fase di dichiarazione dell'array. Con il seguente statement:
#include "stdio.h" int main() { char Nome[10]="Giovanni"; printf("%s\n",Nome); }
assegniamo la stringa, in un unico colpo, all'array, durante l'operazione di dichiarazione. Purtroppo, nel corso del listato, non è possibile eseguire la memorizzazione diretta, come nel seguente caso. Il compilatore, infatti, produrrebbe un messaggio di errore.
#include "stdio.h" int main() { char Nome[10]; Nome="Giovanni"; printf("%s\n",Nome); }
Un altro metodo è quello di utilizzare l'assegnazione come un [...]
ATTENZIONE: quello che hai appena letto è solo un estratto, l'Articolo Tecnico completo è composto da ben 2806 parole ed è riservato agli ABBONATI. Con l'Abbonamento avrai anche accesso a tutti gli altri Articoli Tecnici che potrai leggere in formato PDF per un anno. ABBONATI ORA, è semplice e sicuro.

La gestione delle stringhe nei sistemi DAQ e’ fondamentale quando si deve gestire una interfaccia TUI per l’inserimento di parametri per esempio. A partire da gennaio ci sara’ il corso c raspberry avanzato!
Alla fine, stringhe, variabili, long, char, ecc ecc, sono un concetto umano….. ma si tratta “solo” di bytes, uno dietro l’altro, dentro i meandri della memoria del computer. Anche quando inviamo o riceviamo un files, si ha la sensazione che “qualcosa” transiti nella linea telefonica, mandando delle informazioni all’altra persona.
Nulla di tutto questo: si tratta solo di cambi di stato di due possibili valori, 0 e 1, ma non si invia nulla.
Anche sulla memoria di massa, crediamo che il ns. HD è pieno, vuoto o al 30%, ma i bytes sempre quelli sono…… 🙂