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 opzione -> scelta del nome del programma creato a partire dal codice C 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é