Lezione 5

Transcript

Lezione 5
Lettura da tastiera e scrittura su monitor
Per poter leggere UN SINGOLO CARATTERE dalla tastiera e visualizzare UN SINGOLO
CARATTERE sul monitor si possono utilizzare le funzioni:
int getchar (void) (per leggere dalla tastiera)
int putchar (int) (per visualizzare un carattere sul monitor)
Per utilizzare tali funzioni è necessario richiamare il file stdio.h della libreria standard.
Valori restituiti dalle funzioni:
la funzione getchar() restituisce il codice ASCII del tasto viene premuto
la funzione putchar() restituisce il codice ASCII del carattere che viene visualizzato
Ad esempio, per stampare la lettera 'a' si deve usare l'istruzione:
char lettera = 'a';
putchar (97);
// o anche l'istruzione
putchar (lettera);
// o anche l'istruzione
putchar ('a');
// Tutte queste sono equivalenti a
printf ("%c",lettera);
// oppure a
printf ("%c",'a');
Viceversa, per acquisire un carattere premuto sulla tastiera si usa l'istruzione:
char lettera;
lettera=getchar();
ATTENZIONE : notare la differenza tra
a
rappresenta il nome di una variabile [senza apici]
'a' rappresenta un carattere costante (la lettera dell'alfabeto, a) [singoli apici]
"a" rappresenta una stringa contenente la lettera a [doppi apici]
Esempio
#include < stdio.h >
// per poter usare printf () e getchar()
int main(){
char leggo;
printf ("\ nInserire un carattere : ");
leggo=getchar ();
printf ("\n E\' stato inserito il carattere: %c",leggo);
}
Gestione del buffer di input
In C, l'acquisizione di caratteri immessi mediante tastiera (la tastiera rappresenta il
canale di input standard) avviene in generale in questo modo (trattiamo il caso
semplice dei caratteri, ma il ragionamento rimarrà valido anche per la gestione di tipi di
dati più complessi):
char carattere;
carattere = funzione_di_input(parametri);
ovvero, tramite una generica funzione (qui chiamata funzione_di_input(); un esempio
diretto e' dato dalla funzione getchar()) il valore del carattere digitato sulla tastiera
viene assegnato alla variabile carattere, in modo tale che tale valore possa essere
gestito dall'interno del codice.
In che modo il valore di tale carattere (ovvero, il suo codice ASCII), valore che viene
generato dalla tastiera, cioè da un dispositivo esterno al programma, viene assegnato
alla variabile, che è un elemento interno al programma ?
Esistono due modalità per effettuare questa operazione:
modalità senza buffer
modalità con buffer
Prima di descriverle nel dettaglio, vediamo cosa si intende con buffer. Tale termine
indica, in generale, un'area di memoria temporanea. Nel caso specifico, per buffer si
intende un'area di memoria temporanea in cui vengono temporaneamente salvati i
valori dei caratteri prima che questi ultimi siano passati al programma.
Modalità senza buffer
Nel caso in cui l'input sia gestito in modalità senza buffer i valori dei caratteri vengono
passati direttamente al programma non appena il tasto corrispondente viene premuto,
ovvero il programma non si aspetta che l'utente prema un tasto speciale per far capire
che è terminata l'immissione dei caratteri.
In questa modalità, quindi, nell'istante in cui l'utente preme un tasto il valore del
carattere corrispondente viene passato alla variabile, dichiarata all'interno del
programma, che è preposta alla memorizzazione di tale valore.
NOTA : in C esistono delle funzioni, getche() e getch(), che utilizzano questa modalità
per accettare input da parte dell'utente. Esse sono disponibili all'interno della libreria del
compilatore (includendo il file conio.h) solo su sistemi windows. Per sistemi linux
esistono degli analoghi (v. qui ) ma non fanno parte della libreria standard.
Nel seguito, quindi, faremo uso solamente di getchar()
Modalità con buffer
Nel caso in cui l'input venga gestito mediante un buffer, tutti i valori (=codice ASCII) dei
caratteri inseriti mediante la tastiera ( a prescindere da quanti la funzione inserita nel
programma ne preveda ) vengono salvati temporaneamente nel buffer e rimangono lì
fino a quando l'utente non preme il tasto ENTER. A questo punto, dal buffer vengono
prelevati tanti caratteri quanti la funzione richiamata all'interno del programma ne può
accettare; ad esempio, se uso una funzione che prevede l'immissione di un solo
carattere, dal buffer viene prelevato solo il primo carattere. Gli altri rimangono
disponibili per successive chiamate alla funzione.
getchar() gestisce l'input utilizzando questa modalità.
NOTA : quando viene premuto il tasto ENTER, esso corrisponde a due caratteri,
CR [codice ASCII = 13] ovvero a capo
LF [codice ASCII = 10] ovvero nuova linea
Dei due, il carattere CR viene eliminato dal buffer, mentre il carattere LF vi rimane.
Proviamo a scrivere un programma che ci permetta di "vedere" l'effetto dell'utilizzo del
buffer.
Qual è una possibilità per notare la presenza di quest'area di memoria temporanea ?
Proviamo a riempirla di caratteri e preleviamoli poi, uno per uno, utilizzando la funzione
getchar()
/* inizio codice */
#include <stdio.h>
int main() {
// utilizzeremo questa variabile per leggere dal buffer
char lettura;
printf("\n Inserisci almeno 3 caratteri (e poi premi ENTER o INVIO): ");
lettura = getchar(); // prelevo il primo carattere
// inserisco due "a capo"
putchar('\n');
putchar('\n');
printf("\n ecco il primo carattere del buffer : %c (codice ASCII %d)", lettura,lettura);
// ora preleviamo il secondo carattere
lettura = getchar();
printf("\n ecco il secondo carattere del buffer : %c (codice ASCII %d)",
lettura,lettura);
// ora preleviamo il terzo carattere
lettura = getchar();
printf("\n ecco il terzo carattere del buffer : %c (codice ASCII %d)",lettura,lettura);
// se l'utente ha inserito SOLO 3 CARATTERI, il quarto è il LF (ASCII-> 10)
lettura = getchar();
printf("\n ecco il quarto carattere del buffer : %c (codice ASCII %d)",lettura,lettura);
// visualizziamo un messaggio di avviso, nel caso il quarto sia il carattere LF
printf("\n se l'ultimo carattere letto e\' LF visualizzo 1: -> %d", lettura == 10 );
}
/* fine codice */
Supponiamo ora di creare un file all'interno del quale vengano scritte le istruzioni
riportate qui sopra e di salvarlo dandogli il nome
prova_buffer.c
Compiliamo poi il file, per verificare che non siano presenti errori nel codice
gcc -o prog_buffer prova_buffer.c
gcc
nome del compilatore
-o prog_buffer
C
opzione -> scelta del nome del programma creato a partire dal codice
prova_buffer.c
nome del file contenente il codice C (file da compilare)
Ecco l'output del codice
Oltre ad effettuare operazioni di lettura e visualizzazione possiamo effettuare anche dei
confronti, per determinare quale tipo di carattere sia stato inserito dall'utente
Riprendiamo il codice di prima e stampiamo un messaggio d'avviso che indichi che
siamo in grado di riconoscere le lettere minuscole
Le lettere minuscole possiedono codice ASCII variabile da 97 fino a 122. Quindi una
lettera minuscola, supponiamo sia rappresentata dalla variabile lettera, deve soddisfare
CONTEMPORANEAMENTE a queste condizioni
lettera >= 97
lettera <= 122
quindi l'AND logico tra le due espressioni deve dare come risultato 1 (VERO)
(lettera >= 97 ) && (lettera <= 122)
Se, viceversa, voglio verificare che la lettera NON sia minuscola, allora è sufficiente che
UNA DELLE DUE condizioni che seguono sia verificata
lettera < 97
lettera > 122
quindi l'OR logico tra le due espressioni deve dare come risultato 1 (VERO)
(lettera < 97 ) || (lettera > 122)
/* inizio codice */
#include <stdio.h>
int main() {
// utilizzeremo questa variabile per leggere dal buffer
char lettura;
printf("\n Inserisci almeno 3 caratteri (e poi premi ENTER o INVIO): ");
lettura = getchar(); // prelevo il primo carattere
// inserisco due "a capo"
putchar('\n');
putchar('\n');
printf("\n ecco il primo carattere del buffer : %c",lettura);
printf("\n e\' una lettera minuscola se visualizzo 1 -> %d", (lettura>=97) &&
(lettura<=122) )
printf("\n non e\' una minuscola se visualizzo 1 -> %d", (lettura < 97) || (lettura >
122) )
// ora preleviamo il secondo carattere
lettura = getchar();
printf("\n ecco il secondo carattere del buffer : %c (codice ASCII %d)",
lettura,lettura);
printf("\n e\' una lettera minuscola se visualizzo 1 -> %d", (lettura>=97) &&
(lettura<=122) )
printf("\n non e\' una minuscola se visualizzo 1 -> %d", (lettura < 97) || (lettura >
122) )
// ora preleviamo il terzo carattere
lettura = getchar();
printf("\n ecco il terzo carattere del buffer : %c (codice ASCII %d)",lettura,lettura);
printf("\n e\' una lettera minuscola se visualizzo 1 -> %d", (lettura>=97) &&
(lettura<=122) )
printf("\n non e\' una minuscola se visualizzo 1 -> %d", (lettura < 97) || (lettura >
122) )
// se l'utente ha inserito SOLO 3 CARATTERI, il quarto è il LF (ASCII-> 10)
lettura = getchar();
printf("\n ecco il quarto carattere del buffer : %c (codice ASCII %d)",lettura,lettura);
printf("\n e\' una lettera minuscola se visualizzo 1 -> %d", (lettura>=97) &&
(lettura<=122) )
printf("\n non e\' una minuscola se visualizzo 1 -> %d", (lettura < 97) || (lettura >
122) )
// visualizziamo un messaggio di avviso, nel caso il quarto sia il carattere LF
printf("\n se l'ultimo carattere letto e\' LF visualizzo 1: -> %d", lettura == 10 );
}
/* fine codice */
Esercizio
dichiarare due variabili di tipo char
visualizzare un messaggio in cui si indica all'utente che deve inserire due caratteri
usando la funzione getchar(), memorizzare il primo utilizzando la prima variabile
usando la funzione getchar(), memorizzare il secondo utilizzando la seconda variabile
visualizzare un messaggio per indicare se il primo carattere sia un carattere numerico
visualizzare un messaggio per indicare se il secondo carattere sia un carattere numerico
con UNA SOLA CHIAMATA A PRINTF() visualizzare un messaggio in cui si indica se
entrambi i caratteri siano delle lettere minuscole
chiedere all'utente di inserire un terzo carattere e memorizzarlo nella prima variabile di
tipo char
quest'ultima chiamata a getchar() permette all'utente di insere un carattere ? si/no,
perché