L’input da tastiera in Java Dott. Ing. M. Banci, PhD ) ) ) ) ) ) La lettura di un flusso di input in Java avviene attraverso l'oggetto in della classe System. System.in appartiene alla classe InputStream (letteralmente flusso di input) la quale mette a disposizione un unico metodo, chiamato read(), il quale legge e restituisce un byte dallo stream di input (flusso di ingresso). Per leggere un numero intero, un numero in virgola mobile, una stringa o qualsiasi altro tipo di dato, è necessario eseguire una conversione di tipo. Il modo più comodo e di gran lunga più utilizzato dai programmatori Java, anche se non particolarmente efficiente, è quello di far uso del metodo readLine() messo a disposizione dalla classe BufferedReader. BufferedReader è una classe dedicata alla lettura di buffers (sequenze di caratteri), che il metodo readLine() restituisce sotto forma di stringhe. La classe BufferedReader, a sua volta, deve essere inizializzata fornendo un reader (lettore) di stream di input. Tale lettore è rappresentato da un'instanza della classe InputStreamReader. 15 Giugno 2007 Esercitazione Java - 4 2 ) L'utilità di un lettore è quella di trasformare la sequenza di byte letti tramite l'oggetto System.in (o generalmente tramite un qualsiasi oggetto di tipo InputStream) in una sequenza di caratteri. Secondo gli standard dello schema Unicode adottato Java infatti, un carattere è rappresentato da due byte. ) Cerchiamo di rendere più chiara la situazione spiegando una ad una le operazioni che è necessario fare per leggere una sequenza di byte da un oggetto di tipo InputStream e trasformarli in una stringa. 15 Giugno 2007 Esercitazione Java - 4 3 ) ) L'oggetto System.in, di tipo InputStream, consente di leggere uno ad uno, una sequenza di byte. Trattare con un flusso di byte può risultare complicato e sicuramente poco pratico. E' molto più comodo far uso di un lettore bufferizzato in grado di gestire autonomamente un flusso di byte e convertirlo in un flusso di caratteri. Un lettore bufferizzato può essere creato instanziando un oggetto della classe BufferedStreamReader nel seguente modo: 15 Giugno 2007 Esercitazione Java - 4 4 BufferedStreamReader reader = new BufferedStreamReader (System.in); ) A questo punto faremo uso del lettore bufferizzato che abbiamo chiamato reader per instanziare un oggetto di tipo BufferedReader. Quest'ultimo mette a disposizione del programmatore il metodo readLine() che consente la lettura di intere stringhe. 15 Giugno 2007 Esercitazione Java - 4 5 Per instanziare un oggetto di tipo BufferedReader scriveremo: BufferedReader myInput = new BufferedReader (reader); Abbiamo così definito un nuovo oggetto chiamato myInput sul quale possiamo richiamare il metodo readLine() per leggere una stringa in input dalla tastiera nel seguente modo: str = new String (myInput.readLine()); 15 Giugno 2007 Esercitazione Java - 4 6 ) ) ) La classe BufferedReader, che abbiamo utilizzato per definire l'oggetto myInput, non è una classe dedicata alla lettura di input da tastiera, bensì una classe generica con la quale si possono leggere flussi di dati provenienti da varie fonti (file, altri computer collegati in rete...). Per questo motivo alcuni dei metodi definiti nella classe BufferedReader, tra cui readLine(), prevedono la possibilità che si possa verificare un malfunzionamento. Per malfunzionamento intendiamo ad esempio, la lettura di un file riservato, condizioni di stallo della rete, o in genere una qualsiasi situazione che interrompa il flusso di dati in input. 15 Giugno 2007 Esercitazione Java - 4 7 ) ) ) ) ) Quando si verifica un evento di questo genere, la funzione interessata segnala quanto accaduto all'applicazione principale tramite il lancio di un'eccezione. Un’eccezione è un segnale inviato da un metodo per segnalare qualcosa che non ha funzionato correttamente. Esistono eccezioni diverse per problemi diversi. Nel nostro caso, la funzione readLine() può generare eccezioni di tipo IOException, cioè eccezioni riguardanti il sistema di input-output. Un'applicazione che faccia uso di una funzione che può generare eccezioni deve necessariamente essere in grado di gestire le eventuali eccezioni segnalate. Il problema viene risolto inserendo queste funzioni in un blocco try - catch 15 Giugno 2007 Esercitazione Java - 4 8 try - catch try { istruzione1; } catch (TipoEccezione) { istruzioniDiRecupero; } 15 Giugno 2007 Esercitazione Java - 4 9 ) ) Sostanzialmente può essere tradotto in “prova ad eseguire istruzione1, se qualcosa va storto allora esegui istruzioniDiRecupero” Mettiamo insieme quanto detto fino ad ora e vediamo come scrivere un programma che legga una stringa in input dalla tastiera. 15 Giugno 2007 Esercitazione Java - 4 10 import java.io.InputStreamReader; import java.io.BufferedReader ; import java.io.IOException; public class LeggiStringa { public static void main (String[] args) { InputStreamReader reader = new InputStreamReader (System.in); BufferedReader myInput = new BufferedReader (reader); String str= new String(); try { str = myInput.readLine(); } catch (IOException e) { System.out.println ("Si è verificato un errore: " + e); System.exit(-1); } System.out.println ("Hai scritto: "+str); } } 15 Giugno 2007 Esercitazione Java - 4 11 Nel blocco che abbiamo precedentemente chiamato IstruzioniDiRecupero compaiono due istruzioni: 1. visualizza il tipo di eccezione che si è verificata 2. termina l'esecuzione del programma richiamando il metodo System.exit(). Il parametro passato al metodo exit() è il codice restituito dal processo una volta terminato. Generalmente i processi che terminano correttamente restituiscono zero (0). Il numero -1, restituito in questo caso segnala che il processo è terminato in quanto si è verificato un errore. Per leggere numeri interi e/o in virgola mobile è sufficiente convertire la stringa letta in un numero intero tramite il metodo parseInt(), o in un numero in virgola mobile tramite il metodo parseDouble(), entrambi appartenenti alla classe String. 15 Giugno 2007 Esercitazione Java - 4 12 Convertire stringhe in numeri int k; k = str.parseInt(); nel primo caso e: double k; k = str.parseDouble(); 15 Giugno 2007 Esercitazione Java - 4 13 )Sarà consigliabile prima accertarsi che i dati immessi dall'utente sotto forma di stringa possano essere effettivamente convertiti nel tipo di dato desiderato. 15 Giugno 2007 Esercitazione Java - 4 14