Caratteri e stringhe di caratteri
Una (costante di) stringa è una qualsiasi sequenza di caratteri
racchiusi tra doppi apici, ad es.: “Buon giorno!”.
Una stringa è memorizzata come un vettore di caratteri che termina
con uno speciale marcatore di fine di stringa, detto carattere NULL
e rappresentato dalla sequenza di escape \0.
Ad es., la stringa “Buon giorno!” verrebbe rappresentata in
memoria come
Essa usa 13 locazioni di memoria, e va pertanto dichiarata come
char string[13]
per riservare uno spazio anche per il carattere NULL, che funge da
sentinella per denotare la fine della stringa.
Inizializzazione. La inizializzazione di un vettore di caratteri può
essere semplificata scrivendo una dichiarazione del tipo:
char codici[] = “prova”;
nella quale si usa la stringa prova per inizializzare il vettore
codici, di 6 elementi, come indicato in figura.
I primi 5 elementi consistono nelle lettere p r o v a, l’ultimo è la
sequenza di escape \0 o carattere NULL, che il compilatore C
aggiunge automaticamente alla fine di ogni stringa.
Dato che una stringa è memorizzata come un vettore di caratteri, i
suoi singoli caratteri possono essere immessi, manipolati o messi in
uscita usando le tecniche standard di gestione dei vettori, tramite le
notazioni di indice o di puntatore.
Funzioni di ingresso e uscita
Sebbene, per elaborare una stringa già in memoria, si possa usare
sia una funzione di biblioteca sia una scritta dall’utente, l’immissione
di una stringa da tastiera o la sua visualizzazione sullo schermo
richiedono qualche supporto da funzioni di biblioteca standard.
La tabella seguente elenca le funzioni di biblioteca comunemente
disponibili per l’ingresso e l’uscita di una stringa, sia carattere per
carattere sia come unità completa.
Le definizioni delle funzioni indicate in tabella sono contenute nel file
d’intestazione stdio.h, che pertanto va incluso in ogni programma
che le utilizzi (con la solita direttiva #include <stdio.h>).
Le due funzioni scanf() e printf() sono già state usate
ampiamente. Vediamo perciò le altre quattro funzioni.
Funzione getchar(). La funzione getchar() restituisce il
prossimo carattere battuto alla tastiera. Ha come intestazione:
int getchar()
ed è usata per l’ingresso di singoli caratteri in un’istruzione quale
car_in = getchar();
Essa memorizza il prossimo carattere battuto nella variabile car_in,
ed equivale alla più lunga
scanf(“%c”, &car_in);
getchar() non si aspetta che le vengano passati argomenti, e
restituisce un dato di tipo intero. Ciò per consentire che venga
restituita la sentinella EOF (End-Of-File) già vista, che ha un codice
intero (2610).
getchar() risulta utile per immettere in continuazione stringhe di
caratteri da file di dati, come vedremo più avanti.
Funzione putchar(). La funzione di uscita corrispondente a
getchar() è putchar(), che si aspetta un argomento costituito
da un singolo carattere e lo visualizza sullo schermo. Ad es.
l’istruzione
putchar(‘a’);
visualizza sullo schermo la lettera a, ed è equivalente alla più lunga
printf(“%c”, ‘a’);
Il programma seguente usa le funzioni getchar() e putchar()
per “fare l’eco” sullo schermo dei caratteri battuti sulla tastiera.
#include <stdio.h>
int main()
{
int car_in;
while ((car_in = getchar()) != EOF)
putchar(car_in);
}
Funzioni gets(), puts(). Queste funzioni trattano le stringhe come
unità complete, e sono scritte usando le routine più elementari
getchar() e putchar() (che forniscono l’ingresso e l’uscita di
singoli caratteri).
Un’istruzione quale:
gets(messaggio);
accetta in continuazione i caratteri digitati da tastiera e li memorizza nel
vettore di caratteri messaggio.
La memorizzazione dei caratteri nel vettore termina quando si preme il
tasto <Invio>.
Esso genera un carattere di linea nuova (\n) che gets() traduce in
un carattere NULL (\0), scrivendolo come ultimo carattere nel
vettore messaggio.
Un’istruzione quale:
puts(messaggio);
visualizza sullo schermo il vettore di caratteri messaggio, che
contiene la stringa immessa.
Come mostra la figura, puts() traduce il carattere NULL (\0) in
una sequenza di escape di linea nuova (\n), che invia
automaticamente al video dopo che la stringa è stata visualizzata.
Il seguente programma Getsputs usa gets() e puts() per “fare
l’eco” sullo schermo di una stringa (lunga fino a 80 caratteri)
immessa da tastiera.
#include <stdio.h>
main()
{
char messaggio[81];
printf(“Scrivi una stringa:\n”);
gets(messaggio);
printf(“La stringa appena scritta è:\n”);
puts(messaggio);
}
In esso osserviamo che:
 la funzione gets() accetta in continuazione i caratteri digitati da
tastiera e li memorizza nel vettore di caratteri messaggio;
 la pressione del tasto <Invio> genera un carattere di linea nuova,
\n, che gets() interpreta come un fine-carattere;
 tutti i caratteri incontrati da gets(), tranne quello di linea nuova,
sono memorizzati nel vettore di caratteri messaggio;
 prima di restituire un valore, la funzione gets() aggiunge il
carattere NULL al gruppo di caratteri memorizzati, come mostra la
figura.
B u o n g ... \n
gets()
• il programma usa quindi la funzione puts() per visualizzare la
stringa.
Equivalenza tra puts() e printf(). Si tenga presente che, in
generale,
una chiamata alla funzione puts() può sempre essere
sostituita con una chiamata alla funzione printf()
Ad es., l’istruzione
puts(mesaggio)
usata nel programma precedente può essere sostituita con
l’istruzione
printf(“%s\n”, messaggio);
nella quale
• la sequenza di controllo di conversione %s avverte la funzione che
si accederà a una stringa;
• la sequenza di escape di linea nuova \n sostituisce la linea
nuova generata automaticamente da puts() dopo che la stringa
è stata visualizzata.
Non equivalenza tra gets() e scanf(). L’equivalenza tra le
funzioni di uscita puts() e printf() non è sussiste tra le
funzioni di ingresso gets() e scanf().
Ad es.,
e
gets(messaggio);
scanf(“%s”, messaggio);
non sono equivalenti.
Infatti
• gets() legge un gruppo di caratteri fino a quando incontra un
carattere di linea nuova.
• scanf() legge un gruppo di caratteri fino a quando incontra un
carattere di linea nuova oppure uno spazio vuoto.
Perciò, se si tentasse di immettere nel vettore messaggio i caratteri
Questa è una stringa
usando l’istruzione scanf(“%s”, messaggio); solo la parola
Questa verrebbe assegnata al vettore.
Per immettere la linea completa usando una chiamata alla funzione
scanf() sarebbe necessaria una istruzione del tipo:
scanf(“%s %s %s %s”, mess1, mess2, mess3, mess4);
che assegna
la parola… alla stringa…
Questa
mess1
è
mess2
una
mess3
stringa
mess4
Il fatto che scanf() accetti anche lo spazio vuoto come delimitatore,
la rende poco utile per immettere stringhe di dati.
Osservazione
se si usa la funzione scanf() per immettere una stringa di
dati, davanti al nome del vettore non si usa il carattere &.
Dato che, come sappiamo,
un nome di vettore è una costante puntatore, equivalente all’indirizzo
della prima locazione di memoria riservata per il vettore,
messaggio
è equivalente a
&messaggio[0].
Perciò abbiamo potuto usare la chiamata di funzione
scanf(“%s”, messaggio);
in luogo di
scanf(“%s”, &messaggio[0]);
Manipolazione di stringhe di caratteri
Copia carattere per carattere. Le stringhe si possono manipolare
usando o le tecniche di elaborazione standard dei vettori o le funzioni
di biblioteca standard.
Vediamo dapprima come si elabora una stringa carattere per carattere,
il che farà capire come sono costruite le funzioni di biblioteca
standard e come creare funzioni di biblioteca proprie.
Costruiamo una funzione, strcopia(), che copi la stringa2 nella
stringa1.
void strcopia(char string1[], char string2[])
{
int i = 0;
while (string2[i] != ‘\0’)
{
string1[i] = string2[i];
++i;
}
string1[i] = ‘\0’;
return;
}
Sebbene questa funzione possa essere abbreviata e scritta in maniera
più compatta, essa illustra le caratteristiche principali della
manipolazione di stringhe.
Nella linea d’intestazione, le due stringhe sono passate a
strcopia() come vettori, quindi ciascun elemento di string2 è
copiato nell’elemento corrispondente di string1 fino a che
(while) s’incontra il marcatore di fine-stringa NULL (\0), la cui
rilevazione fa terminare il ciclo while che copia gli elementi.
Dato che il carattere NULL non è copiato da string2 a string1,
l’ultima istruzione di strcopia() aggiunge a string1 un
carattere di fine-stringa.
Prima di chiamare strcopia(), si deve allocare spazio sufficiente
per il vettore string1, in modo che possa accogliere gli elementi di
string2.
Il programma seguente alloca per ciascuno dei due vettori lo spazio
di una linea di schermo completa (80 caratteri), più uno per il finestringa, dichiara la funzione strcopia() che si aspetta due
vettori di caratteri e la chiama passandole gli indirizzi dei due
vettori.
#include <stdio.h>
void main(void)
{
char messaggio[81];
char nuovo_mess[81];
int i;
void strcopia(char [], char []);
printf("Scrivi una frase:");
gets(messaggio);
strcopia(nuovo_mess, messaggio);
puts(nuovo_mess);
}
void strcopia(char string1[], char string2[])
{
int i = 0;
while (string2[i] != '\0')
{
string1[i] = string2[i];
++i;
}
string1[i] = '\0';
return;
}
Immissione di stringhe carattere per carattere. Con la stessa
tecnica con cui può esere copiata carattere per carattere, una
stringa può essere anche immessa e visualizzata.
Ad es., il programma seguente usa la funzione d’ingresso caratteri
getchar() per fare immettere una stringa carattere per carattere.
#include <stdio.h>
void main(void)
{
char messaggio[81], c;
int i;
printf("Scrivi una frase:\n");
i = 0;
while(i<80 && (c = getchar()) != '\n')
{
messaggio[i] = c;
++i;
}
messaggio[i] = '\0';
printf("La frase appena scritta è:\n");
puts(messaggio);
}
La parte di programma evidenziata in colore sostituisce l’istruzione
gets(messaggio) usata nel programma Getsputs.
L’istruzione while fa leggere i caratteri immessi purché il loro
numero sia inferiore a 81 e il carattere restituito da getchar()
non sia quello di linea nuova (\n).
Osservazione. Le parentesi attorno all’espressione c =
getchar() sono necessarie per assegnare il carattere restituito da
getchar() alla variabile c prima di confrontarlo con una
sequenza di linea nuova (\n).
In loro assenza, dato che l’operatore di confronto != ha la
precedenza su quello di assegnazione =, l’espressione sarebbe
equivalente a
c = (getchar() != ‘\n’)
Essa confronta il carattere restituito da getchar() con ‘\n’, e il
valore dell’espressione relazionale (getchar() != ‘\n’) è 0
o 1 a seconda che getchar() abbia ricevuto o no il carattere di
linea nuova. Così anche il valore assegnato a c sarebbe 0 o 1, a
seconda del risultato del confronto.
Funzione scritta dall’utente. Il programma precedente illustra anche
un’utile tecnica per sviluppare le funzioni.
Le istruzioni evidenziate in colore costituiscono una unità
autoconsistente per immettere una linea completa di caratteri da
tastiera.
Pertanto esse possono essere scorporate da main() e messe
insieme in una nuova funzione, chiamata getlinea(), come
illustrato nel programma seguente.
#include <stdio.h>
void main(void)
{
char messaggio[81];
int i;
void getlinea(char []);
printf("Scrivi una frase:\n");
getlinea(messaggio);
printf("La frase appena scritta è:\n");
puts(messaggio);
}
void getlinea(char strin[])
{
int i = 0;
char c;
while (i < 80 && (c = getchar()) != '\n')
{
strin[i] = c;
++i;
}
strin[i] = '\0';
return;
}
Una scrittura compatta. Possiamo anche riscrivere getlinea()
in modo più compatto assegnando direttamente alle componenti del
vettore strin i caratteri restituiti da getchar(), eliminando la
variabile locale c.
void getlinea(char strin[])
{
int i = 0;
while (i < 80 && (strin[i++] = getchar()) != '\n')
;
strin[i] = '\0';
return;
}
Osservazione. L’istruzione di assegnazione
(strin[i++] = getchar())
•assegna il carattere restituito da gethcar() direttamente al vettore
strin, quindi
•incrementa il subscritto i usando l’operatore postfisso ++.
• la successiva istruzione NULL (;) soddisfa l’esigenza che un ciclo
while contenga almeno una istruzione.
Entrambe le versioni di getlinea() sono sostituti accettabili di
gets(), e dimostrano la intercambiabilità delle funzioni di biblioteca
del C con quelle scritte dall’utente.
Puntatori e funzioni di biblioteca
Nel costruire funzioni di gestione delle stringhe risultano
particolarmente utili i puntatori: una notazione con puntatori dà
luogo a istruzioni più compatte ed efficienti - rispetto agli indici - per
accedere ai caratteri individuali di una stringa.
Per vedere l’equivalenza tra indici e puntatori quando si accede ai
singoli caratteri di una stringa riprendiamo in considerazione la
funzione strcopia(), che copia i caratteri da un vettore a un
altro, uno alla volta.
void strcopia(char string1[], char string2[])
{
int i = 0;
while (string2[i] != '\0')
{
string1[i] = string2[i];
++i;
}
string1[i] = '\0';
return;
}
Per scriverne una versione con puntatori, apportiamole due modifiche:
1. Osserviamo che l’espressione
(string2[i] != '\0')
• è vera (cioè ha un valore diverso da 0) fin tanto che si leggono i
caratteri della stringa diversi da quello finale (\0), mentre
• è falsa (cioè vale 0) solo quando si legge il carattere finale.
Ma anche l’espressione string2[i] ha un valore diverso da 0 per
tutti i caratteri della stringa tranne l’ultimo, dato che solo \0 ha il
codice ASCII 0.
Perciò si può sostituire l’espressione
(string2[i] != '\0')
con la più semplice
string2[i]
e scrivere:
void strcopia(char string1[], char string2[])
{
int i = 0;
while (string2[i])
{
string1[i] = string2[i];
++i;
}
string1[i] = '\0';
return;
}
2. L’istruzione di assegnazione
string1[i] = string2[i];
ha come valore il codice ASCII del carattere via via copiato; esso è
uguale a 0 solo dopo che il carattere NULL sia stato assegnato a
string1.
Perciò possiamo includere l’espressione di assegnazione
string1[i] = string2[i] dentro la parte di test dell’istruzione
while, scrivendo:
void strcopia(char string1[], char string2[])
{
int i = 0;
while (string1[i] = string2[i])
++i;
return;
}
In tal modo non è necessario terminare esplicitamente la prima stringa
con il carattere NULL, dato che l’assegnazione entro parentesi
assicura che NULL sia copiato dalla seconda stringa nella prima,
facendo terminare correttamente il ciclo while.
Possiamo adesso convertire strcopia() dalla notazione con indici
a quella con puntatori come segue:
void strcopia(char *string1, char *string2)
{
while (*string1 = *string2)
{
string1++;
string2++;
}
return;
}
Sia nella versione con indici, sia in quella con puntatori, la funzione
strcopia() riceve il nome del vettore passato (ossia l’indirizzo
della sua prima locazione).
Nella versione con puntatori di strcopia() i due indirizzi passati
sono memorizzati rispettivamente negli argomenti puntatore
string1 e string2.
La precedente dichiarazione
(char *string1, char *string2)
indica che string1 e string2 sono puntatori che contengono
l’indirizzo di un carattere, e fa sì che gli indirizzi passati siano trattati
come valori puntatori anziché come nomi di vettori.
La dichiarazione è equivalente a:
(char string1[], char string2[])
All’interno di strcopia() l’espressione puntatore *string1
(”l’elemento il cui indirizzo è in string1”), sostituisce l’espressione
con subscritto equivalente string1[i]. Analogamente per
*string2.
L’espressione
*string1 = *string2
fa sì che l’elemento puntato da string2 sia assegnato all’elemento
puntato da string1.
Dato che gli indirizzi di partenza di entrambe le stringhe sono passati
a strcopia() e memorizzati rispettivamente in string2 e
string1, l’espressione *string2 si riferisce inizialmente a
string2[0], e *string1 a string1[0].
Gli incrementi consecutivi ai due puntatori in strcopia() con le
istruzioni string1++; e string2++; fanno sì che ciascun
puntatore punti al carattere successivo nella rispettiva stringa.
Si può effettuare un ultimo cambiamento alla funzione includendo gli
incrementi ai puntatori come operatori postfissi nella parte di test
dell’istruzione while.
La forma finale della funzione di copia stringa è allora:
void strcopia(char *string1, char *string2)
{
while (*string1++ = *string2++)
;
return;
}
Nell’espressione *string1++ = *string2++ non c’è ambiguità,
anche se l’operatore di indirezione, *, ha la stessa precedenza di
quello di incremento, ++, infatti essa fa accedere al carattere
puntato prima che il puntatore sia incrementato.
Solo dopo il completamento dell’assegnazione *string1++ =
*string2++ i puntatori sono incrementati per puntare ai
caratteri successivi nelle rispettive stringhe.
Quasi tutti i compilatori C comprendono nella loro biblioteca
standard una funzione di copia stringa, scritta esattamente come
la nostra versione con puntatori di strcopia().
Funzioni di biblioteca di stringa. Quasi tutti i compilatori C
dispongono di un gruppo di funzioni di biblioteca per:




l’ingresso
il confronto
la manipolazione
l’uscita
di stringhe di caratteri. Un loro elenco è fornito nella tabella seguente:
Esercizio. Inserire gli opportuni commenti nelle righe lasciate vuote
del seguente programma, quindi indicare l’uscita prodotta dal
programma, senza eseguirlo.
#include <stdio.h>
#include <string.h>
int main()
{
char x[] = "Buon compleanno a te";
char y[25];
char z[15];
printf("%s%s\n%s%s\n",
"La stringa nel vettore x è: ", x,
"La stringa nel vettore y è: ", strcpy(y, x));
strncpy(z, x, 14);
z[14] = '\0';
printf("La stringa nel vettore z è: %s\n", z);
return(0);
}
#include <stdio.h>
#include <string.h>
int main()
{
char x[] = "Buon compleanno a te";
/* inizializza il vettore di caratteri x */
char y[25];
/* crea il vettore di caratteri y */
char z[15];
/* crea il vettore di caratteri z */
printf("%s%s\n%s%s\n",
"La stringa nel vettore x è: ", x,
"La stringa nel vettore y è: ", strcpy(y, x));
strncpy(z, x, 14);
/* copia i primi 14 caratteri di x in z
(non copia il carattere nullo) */
z[14] = '\0';
printf("La stringa nel vettore z è: %s\n", z);
return(0);
}
Il programma precedente utilizza le funzioni:
• strcpy() per copiare l’intera stringa x nel vettore y
• strncpy() per copiare i primi 14 caratteri della stringa x nel
vettore z.
Al vettore z viene accodato un carattere NULL (\0) perché la
chiamata di strncpy() nel programma non scrive un carattere
nullo di terminazione, dato che il 3° argomento è inferiore alla
lunghezza della stringa indicata dal 2° argomento.
Esercizio. Inserire gli opportuni commenti nelle righe lasciate vuote
del seguente programma, quindi indicare l’uscita prodotta dal
programma, senza eseguirlo.
#include <stdio.h>
#include <string.h>
int main()
{
char s1[20] = "Happy ";
char s2[] = "New Year ";
char s3[40] = "";
printf("s1 = %s\ns2 = %s\n", s1, s2);
printf("strcat(s1, s2) = %s\n", strcat(s1, s2));
printf("strncat(s3,s1,6) = %s\n", strncat(s3,s1,6));
printf("strcat(s3,s1) = %s\n", strcat(s3,s1));
return(0);
}
#include <stdio.h>
#include <string.h>
int main()
{
char s1[20] = "Happy ";
/* inizializza il vettore di caratteri s1 */
char s2[] = "New Year ";
char s3[40] = "";
/* inizializza il vettore di caratteri s3
con la stringa vuota */
printf("s1 = %s\ns2 = %s\n", s1, s2);
printf("strcat(s1, s2) = %s\n", strcat(s1, s2));
/* accoda s2 a s1 */
printf("strncat(s3,s1,6) = %s\n", strncat(s3,s1,6));
/* accoda i primi 6 caratteri di s1 a s3;
inserisce \0 dopo l’ultimo carattere */
printf("strcat(s3,s1) = %s\n", strcat(s3,s1));
/* accoda s1 a s3 */
return(0);
}
Il programma precedente usa due funzioni:
strcat()
accoda il suo 2° argomento (una stringa) al 1°, che è un vettore di
caratteri che contiene una stringa.
Il 1° carattere del 2° argomento sostituisce il carattere NULL (\0) che
termina la stringa del 1° argomento.
Il vettore utilizzato per immagazzinare la prima stringa deve essere
sufficientemente grande per contenere:
• la prima stringa,
• la seconda stringa,
• il carattere nullo di terminazione che viene copiato dalla 2^ stringa.
strncat()
accoda un numero specificato di caratteri dalla 2^ stringa alla 1^.
Al risultato viene accodato automaticamente un carattere NULL di
terminazione.
Funzioni per la conversione delle stringhe (atof(), atoi(),
atol())
La biblioteca di utilità generiche <stdlib.h> del C contiene funzioni
che convertono le stringhe formate da numeri in valori interi e in
virgola mobile, indicate in Tabella.
La funzione atof() restituisce il suo argomento, costituito da una
stringa che rappresenta un numero in virgola mobile, convertito in
un numero in doppia precisione.
Nel caso in cui il valore non possa essere convertito (per esempio, se
il primo carattere della stringa non è un numero), il comportamento
di atof() sarà indefinito.
Esempio di atof(). Scrivere un programma che converta una
stringa in un numero in doppia precisione, e che produca la
seguente uscita:
La stringa “99.0” convertita in double è 99.00
Il valore convertito, diviso 2 è: 49.500
Un programma che soddisa la richiesta è il seguente:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double d;
d = atof("99.0");
printf("%s%.3f\n%s%.3f\n",
"La stringa \"99.0\" convertita in double è ", d,
"Il valore convertito, diviso 2 è: ", d/2.0);
}
Esempio di atoi(). In modo analogo si comporta la funzione
atoi(), che converte in un valore intero il suo argomento costituito
da una stringa di cifre che rappresenta un intero.
Consideriamo il seguente programma:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
i = atoi("2006");
printf("%s%d\n%s%d\n",
"La stringa \"2006\" convertita in int è: ", i,
"Il valore convertito, meno 6, è: ", i - 6);
}
Esempio di atol(). La funzione atol() restituisce il suo
argomento, costituito da una stringa che rappresenta un numero
intero lungo, convertito in un valore (intero) lungo.
Qualora gli int e i long siano rappresentati entrambi mediante 4
byte, le funzioni atoi() e atol() funzionano in modo identico.
Consideriamo il seguente programma:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long l;
l = atol("12345678");
printf("%s%ld\n%s%ld\n",
"La stringa \"12345678\" convertita in long è: ", l,
"Il valore convertito, diviso 2, è: ", l / 2);
}
Funzioni di biblioteca di carattere (ctype.h)
Vi sono anche funzioni per operare sui caratteri, alcune delle quali
sono elencate nella tabella seguente:
Queste funzioni sono inserite in un file standard di nome ctype.h,
per cui per accedere a esse il programma dovrà contenere, prima
di main(), l’istruzione
#include <ctype.h>
Esempio (toupper(), tolower()). Come primo esempio,
consideriamo il programma seguente:
#include <stdio.h>
int main()
{
printf("%s%c\n %s%c\n %s%c\n",
" u convertito in maiuscolo è ", toupper('u'),
"7 convertito in maiuscolo è ", toupper('7'),
"L convertito in minuscolo è ", tolower('L'));
}
Esso produce la seguente uscita:
u convertito in maiuscolo è U
7 convertito in maiuscolo è 7
L convertito in minuscolo è l
Esempio (isalpha(), isdigit()). Come altro esempio
consideriamo il programma seguente, che chiede in continuazione
all’utente di immettere un carattere, quindi stabilisce se esso sia
una lettera o una cifra.
Il programma contiene un ciclo do-while dal quale si esce quando
si digita una f.
Per non costringere l’utente a scrivere lettere minuscole o maiuscole,
esso converte tutte le lettere scritte in minuscole.
#include <stdio.h>
#include <ctype.h>
void main(void)
{
char car_ingr;
do
{
printf("\nPremi un tasto qualsiasi (f per finire) ");
car_ingr = getchar();
/*riceve il prossimo carattere*/
car_ingr = tolower(car_ingr);
/*converte in minuscolo*/
getchar();
/*riceve e ignora il tasto Invio*/
if (isalpha(car_ingr)) /*un valore diverso da 0 è vero*/
printf("Il carattere immesso è una lettera.\n");
else if (isdigit(car_ingr))
printf("Il carattere immesso è una cifra.\n");
else
printf("Il carattere non è né lettera né cifra.\n");
}
while (car_ingr != 'f');
}
Osserviamo che, poiché le funzioni restituiscono un valore, una funzione
può essa stessa essere l’argomento di una funzione (compresa se
stessa).
Perciò le due istruzioni del programma precedente
car_ingr = getchar();
car_ingr = tolower(car_ingr);
possono essere fuse nell’unica istruzione:
car_ingr = tolower(getchar());
Scarica

Fonda20