Corso C su Raspberry PI partendo da zero: La gestione delle stringhe

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.

 

Figura 1: Definizione di un array composto da 10 elementi.

Figura 1: Definizione di un array composto da 10 elementi.

 

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);
}

 

Figura 2: Come un array ospita la stringa.

Figura 2: Come un array ospita la stringa.

 

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 PLATINUM. Con l'Abbonamento avrai anche accesso a tutti gli altri Articoli Tecnici PREMIUM e PLATINUM e potrai fare il download (PDF) di tutti gli EOS-Book, Firmware e degli speciali MONOTEMATICI. ABBONATI ORA con PAYPAL è semplice e sicuro.

Abbonati alle riviste di elettronica

2 Commenti

  1. Maurizio Di Paolo Emilio Maurizio 1 novembre 2016
  2. Giovanni Di Maria Giovanni Di Maria 1 novembre 2016

Scrivi un commento

ESPertino è la nuova scheda per IoT compatibile ARDUINO.
Scopri come averla GRATIS!