Stringhe di caratteri

 


 

Le stringhe come particolari array di caratteri

 

Abbiamo già visto che le stringhe non costituiscono un tipo intrinseco del C++ e di conseguenza non sono ammesse come operandi dalla maggior parte degli operatori (compreso l'operatore di assegnazione).

Sono tuttavia riconosciute da alcuni operatori (come per esempio gli operatori di flusso di I/O del C++) e da numerose funzioni di libreria del C (come per esempio la printf, insieme a molte altre che hanno il compito specifico di manipolare le stringhe).

In memoria le stringhe sono degli array di tipo char, con una particolarità in più, che le fa riconoscere da operatori e funzioni come stringhe e non come normali array: l'elemento dell'array che segue l'ultimo carattere della stringa deve contenere il carattere NULL (detto in questo caso terminatore); si dice pertanto che una stringa é un "array di tipo char null terminated".

 


 

Definizione di variabili stringa

 

Consideriamo il seguente esempio. L'istruzione:

                                char MiaVar[30];

definisce la variabile MiaVar come array di tipo char con massimo 30 elementi, ma non ancora come stringa. Affinché MiaVar sia identificata da operatori e funzioni come stringa, dobbiamo non solo definire una variabile array di tipo char, ma anche inserire nell'array una serie di caratteri terminata da un NULL.
Per esempio, se vogliamo che MiaVar presenti a operatori e funzioni la stringa "Ciao", dobbiamo scrivere le istruzioni:

                                                    MiaVar[0] = 'C';
                                                    MiaVar[1] = 'i';
                                                    MiaVar[2] = 'a';
                                                    MiaVar[3] = 'o';
                                                    MiaVar[4] = '\0';

impegnando così 5 elementi dell'array dei 30 disponibili (i rimanenti 25 saranno ignorati).

 


 

Inizializzazione di variabili stringa

 

Benché le stringhe non siano ammesse nelle operazioni di assegnazione, lo sono in quelle di inizializzazione (il che conferma che si tratta di due operazioni diverse!):

Sequenza non valida                               Sequenza valida
char Saluto[10]; char Saluto[10] = "Ciao";
Saluto = "Ciao";

Nelle inizializzazioni si utilizzano le costanti stringa, i cui caratteri vengono inseriti nei primi elementi dell'array dichiarato; il terminatore viene aggiunto automaticamente nell'elemento successivo a quello in cui é stato inserito l'ultimo carattere. La stringa può essere "allungata" fino a un massimo di caratteri (terminatore compreso) pari alla dimensione dell'array.

E' anche possibile inizializzare una stringa come un normale array; in questo caso, però, il terminatore deve essere inserito esplicitamente:
                                                      char Saluto[] = { 'C', 'i', 'a', 'o', '\0' };
ovviamente questa seconda forma, inutilmente più "faticosa", non é mai usata!

Se nella inizializzazione si omette la dimensione dell'array, questa viene automaticamente definita dalla lunghezza della costante stringa aumentata di uno, per far posto al terminatore (in questo caso la stringa non può più essere "allungata"!):

             char Saluto[] = "Ciao";             (allocato in memoria array con 5 elementi).

In caso che si creino delle stringhe con un numero di caratteri (compreso il terminatore) maggiore di quello dichiarato, il programma non produce direttamente messaggi di errore, ma invade zone di memoria non di sua pertinenza, con conseguenze imprevedibili (spesso si verifica un errore fatale a livello di sistema operativo).

  [p17]

 


 

Funzioni di libreria gets e puts

 

Benché le funzioni gets e puts facciano parte della libreria di I/O del C, il loro uso é abbastanza frequente anche in programmi C++, a causa di alcune peculiarità che le distinguono da tutte le altre funzioni di I/O.

La funzione gets(argomento) trasferisce l'intero buffer di input di stdin nella variabile stringa argomento, riconoscendo come unico terminatore il carattere new-line ('\n') (che é sempre l'ultimo carattere del buffer) e sostituendolo con il carattere NULL ('\0'). Ne consegue che la stringa può contenere anche blanks e tabulazioni (a differenza dalle stringhe lette mediante cin o le altre funzioni di input del C). In pratica, la gets legge da tastiera un'intera riga di testo, compreso il ritorno a capo che trasforma nel terminatore della stringa.

La funzione puts(argomento) trasferisce in stdout il contenuto della variabile stringa argomento, sostituendo il terminatore di stringa NULL con il carattere new-line. In pratica, la puts scrive su video un'intera riga di testo, compreso il ritorno a capo.

In entrambi i casi la variabile argomento deve essere stata definita (nel programma chiamante) come array di tipo char.

 


 

Conversioni fra stringhe e numeri

 

Le conversioni fra stringhe (contenenti caratteri numerici) e numeri (e viceversa) non si possono fare direttamente mediante casting, in quanto le stringhe sono degli array e, in più, ogni elemento che le costituisce è convertibile nel corrispondente codice ascii, non nel valore numerico della cifra rappresentata.
Es.:  int('1')  da' come risultato il numero 49 (codice ascii del carattere 1) e non il numero 1

Bisogna invece ricorrere a opportune funzioni di libreria.

 

  Conversioni da stringhe a numeri - Le funzioni atoi e atof

Per convertire una stringa in un numero, la via più semplice è usare le funzioni di libreria (del C) atoi e atof :

Entrambe le funzioni vanno utilizzate includendo l'header-file: <stdlib.h>

Il processo di conversione si interrompe (con il numero calcolato fino a quel momento) appena è incontrato un carattere non valido (senza messaggi di errore). Se nessun carattere è convertito atoi e atof ritornano rispettivamente 0 e 0.0

 

  Conversioni da numeri a stringhe - La funzione sprintf

Per convertire numeri in stringhe, è più conveniente (rispetto ad altre possibilità) usare la funzione di libreria (del C) sprintf. Infatti questa funzione, non solo esegue la conversione, ma permette anche di ottenere una stringa formattata nel modo desiderato.

All'inizio di questo corso abbiamo trattato della funzione printf, che utilizza gli specificatori di formato per scrivere dati sul dispositivo standard di output (stdout). La funzione sprintf é identica alla printf salvo il fatto che scrive in una stringa anziché su stdout. Richiede due argomenti fissi, seguiti da un numero qualsiasi di argomenti opzionali:

  [p18]

 


 

Le stringhe in C++

 

Le stringhe descritte finora sono quelle "in stile C". In C++ si usano ancora, ma si ricorre più spesso alla classe string della Libreria Standard, che offre maggiori flessibilità e incapsula tutte le funzioni di manipolazione delle stringhe.

 


 

Torna all'Indice