Appendice A: utilizzo classe Scanner

Tutorial su classe java.util.Scanner

La classe java.util.Scanner è una classe di utilità per leggere da vari input e ha metodi comodi per lavorare con l'input. Scanner è una classe wrapper di sorgenti di input. Le sorgenti i input possono essere un oggetto di tipo Reader, un InputStream, una String o un File.

Si può usare Scanner per leggere da standard input:

Scanner standardInputScanner = new Scanner(System.in);

e se charSource è di tipo Reader, si può creare uno Scanner per leggere da charSource, così:

Scanner scanner = new Scanner(charSource);

Quando processa un input Scanner lavora con tokens. Un token è una stringa di caratteri che non può essere ulteriormente separata. Un token può essere una singola parola o una stringa di caratteri che rappresenta un valore di tipo double. Nel caso di uno scanner, i tokens sono separati da "delimitatori". I delimitatori sono caratteri di spazio, tabs e caratteri di fine linea. Normalmente i caratteri spazio sono utilizzati per separare le parole e sono scartati dallo scanner. Lo scanner a metodi d'istanza per leggere tokens di vario tipo.

Supponendo che la variabile stdin sia di tipo Scanner, abbiamo la funzione stdin.netxInt() che legge un valore di tipo int dall'utente e lo ritorna. Ci sono metodi corrispondenti per leggere altri tipi, inclusi stdin.nextDouble(), stdin.nextLong() e stdin.nextBoolean() (accetta sono "true" o "false" come input). Il metodo stdin.nextLine() legge una riga di input e stdin.next() ritorna una stringa di non spazi vuoti.

Esempio di programma che legge da console, i parametri di input, valori double di quantità investita, tasso di interesse e calcola in un anno, il valore dell'interesse e il nuovo capitale:

import java.util.Scanner;

public class Interest2WithScanner {
	public static void main(String[] args) {
		Scanner stdin = new Scanner(System.in); // Create the Scanner.
		double principal; // The value of the investment.
		double rate; // The annual interest rate.
		double interest; // The interest earned during the year.
		System.out.print("Enter the initial investment: ");
		principal = stdin.nextDouble();
		System.out.print("Enter the annual interest rate (as a decimal): ");
		rate = stdin.nextDouble();
		interest = principal * rate; // Compute this year’s interest.
		principal = principal + interest; // Add it to principal.
		System.out.printf("The amount of interest is $%1.2f%n", interest);
		System.out.printf("The value after one year is $%1.2f%n", principal);
	} // end of main()
} // end of class Interest2WithScanner

Se il valore immesso dall'utente con è compatibile con quello dalla funzione di Scanner, viene lanciata un'eccezione di tipo runtime, java.util.InputMismatchException.

Ad esempio, se digito "ciao" quando mi chiede la quantità da investire, viene sollevata l'eccezione:

Enter the initial investment: ciao
Exception in thread "main" java.util.InputMismatchException
	at java.util.Scanner.throwFor(Scanner.java:864)
	at java.util.Scanner.next(Scanner.java:1485)
	at java.util.Scanner.nextDouble(Scanner.java:2413)
	at Interest2WithScanner.main(Interest2WithScanner.java:10)

Ricapitolando, ammettiamo di avere una variabile scanner di tipo Scanner. Allora noi abbiamo:

  • scanner.next() - legge il prossimo token dalla sorgente di input e ritorna come String;

  • scanner.nextInt(), scanner.nextDouble(), e così via - legge il prossimo token dalla sorgente di input e cerca di convertirlo in tipo int, double e così via. Ci sono metodi per leggere valori di ogni tipo primitivo;

  • scanner.nextLine() - legge una riga intera, fino alla prossima riga, e ritorna la riga come String. Il carattere di fine linea è letto ma non fa parte della stringa ritornata. Nota che questo metodo non è basato sui token. Un'intera riga è letta e ritornata inclusi i caratteri di spazio presenti nella riga. Il valore di ritorno può anche essere una stringa vuota.

Tutti questi metodi possono generate delle eccezioni. Se un tentativo è fatto per leggere oltre la fine dell'input, è lanciata un'eccezione java.util.NoSuchElementException. Metodi come scanner.nextInt() lanciano un'eccezione di tipo java.util.InputMistmatchException se il token successivo nell'input non rappresenta un valore del tipo richiesto. Le eccezioni che possono essere generate non richiedono una gestione delle eccezioni obbligatoria, in quanto eccezioni di tipo runtime.

La classe Scanner, ha anche dei metodi per testare il tipo di input successivo. Possiamo interrogare lo scanner per sapere se ci sono altri token dopo o se il token successivo è del tipo desiderato:

  • scanner.hasNext() - ritorna un valore boolean true, se c'è almeno un atro token nello stream di input;

  • scanner.hasNextInt(), scanner.hasNextDouble(), .... - ritorna un valore boolean true se c'è almeno un altro token nello stream di input e se il token rappresenta un valore nel tipo cercato;

  • scanner.hasNextLine() - ritorna un valore boolean true se almeno un'altra riga nello stream di input;

Last updated