Leggere l'input da tastiera
La lettura di un flusso di input in Java avvieneattraverso l'oggetto in della classeSystem. System.in appartiene alla classeInputStream (letteralmente flusso di input) la qualemette a disposizione un unico metodo, chiamato read(),il quale legge e restituisce un byte dallo streamdi input (flusso di ingresso). Per leggere un numerointero, un numero in virgola mobile, una stringa o qualsiasialtro tipo di dato, è necessario eseguire unaconversione di tipo. Il modo più comodo e di granlunga più utilizzato dai programmatori Java, anche senon particolarmente efficiente, è quello di far usodel metodo readLine() messo a disposizione dallaclasse BufferedReader. BufferedReader èuna classe dedicata alla lettura di buffers (sequenzedi caratteri), che il metodo readLine() restituiscesotto forma di stringhe. La classe BufferedReader, asua volta, deve essere inizializzata fornendo unreader (lettore) di stream di input. Tale lettoreè rappresentato da un'instanza della classeInputStreamReader. L'utilitàdi un lettore è quella di trasformare la sequenza dibyte letti tramite l'oggetto System.in (ogeneralmente tramite un qualsiasi oggetto di tipoInputStream) in una sequenza di caratteri. Secondo glistandard dello schema Unicode adottato Java infatti,uncarattere è rappresentato da due byte. Cerchiamo direndere più chiara la situazione spiegando una ad unale operazioni che è necessario fare per leggere unasequenza di byte da un oggetto di tipo InputStream etrasformarli in una stringa.
-
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:
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. 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());
Ma non finisce qui. La classe BufferedReader, cheabbiamo utilizzato per definire l'oggetto myInput,non è una classe dedicata alla lettura di input datastiera, bensì una classe generica con la quale sipossono leggere flussi di dati provenienti da varie fonti(file, altri computer collegati in rete...). Per questomotivo alcuni dei metodi definiti nella classeBufferedReader, tra cui readLine(), prevedonola possibilità che si possa verificare unmalfunzionamento. Per malfunzionamento intendiamo ad esempio,la lettura di un file riservato, condizioni di stallo dellarete, o in genere una qualsiasi situazione che interrompa ilflusso di dati in input. Quando si verifica un evento diquesto genere, la funzione interessata segnala quantoaccaduto all'applicazione principale tramite il lancio diun'eccezione. Il meccanismo delle eccezioni Javaverrà analizzato più avanti, per ora vi bastisapere che un eccezione è un segnale inviato da unmetodo per segnalare qualcosa che non ha funzionatocorrettamente. Esistono eccezioni diverse per problemidiversi. 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 chepuò generare eccezioni deve necessariamente essere ingrado di gestire le eventuali eccezioni segnalate. Ilproblema viene risolto inserendo queste funzioni in un bloccotry - catch, la cui sintassi è la seguente:
try {istruzione1; } catch (TipoEccezione) {istruzioniDiRecupero;}
che sostanzialmente può essere tradotto in"prova ad eseguire istruzione1, se qualcosa va stortoallora esegui istruzioniDiRecupero"
Mettiamo insieme quanto detto fino ad ora e vediamo comescrivere un programma che legga una stringa in input dallatastiera.
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); } }
Nel blocco che abbiamo precedentemente chiamatoIstruzioniDiRecupero compaiono due istruzioni; laprima visualizza il tipo di eccezione che si èverificata, la seconda termina l'esecuzione del programmarichiamando il metodo System.exit(). Il parametropassato al metodo exit() è il codice restituitodal processo una volta terminato. Generalmente i processi cheterminano correttamente restituiscono zero (0). Il numero -1,restituito in questo caso segnala che il processo èterminato in quanto si è verificato un errore.
Abbiamo visto come sia possibile leggere delle stringhe,tuttavia all'inizio del capitolo ci eravamo posti comeobbiettivo la lettura oltre che di oggetti di tipo stringa,anche di numeri interi, o in virgola mobile. Per farciò è sufficiente convertire la stringa lettain un numero intero tramite il metodo parseInt(), o inun numero in virgola mobile tramite il metodoparseDouble(), entrambi appartenenti alla classeString. Le istruzioni da utilizzare saranno quindi:
int k;k = str.parseInt();
nel primo caso e:
double k;k = str.parseDouble();
nel secondo. Ovviamente sarà consigliabile primaaccertarsi che i dati immessi dall'utente sotto forma distringa possano essere effettivamente convertiti nel tipo didato desiderato.
[Pending: assicurarsi che i dati siano convertibili]