Java Language
Scanner
Ricerca…
Sintassi
- Scanner scanner = nuovo scanner (fonte di origine);
- Scanner scanner = nuovo scanner (System.in);
Parametri
Parametro | Dettagli |
---|---|
fonte | L'origine potrebbe essere uno di String, File o qualsiasi tipo di InputStream |
Osservazioni
La classe Scanner
è stata introdotta in Java 5. Il metodo reset()
è stato aggiunto in Java 6 e un paio di nuovi costruttori sono stati aggiunti in Java 7 per l'interoperabilità con la (allora) nuova interfaccia Path
.
Lettura dell'input del sistema tramite Scanner
Scanner scanner = new Scanner(System.in); //Scanner obj to read System input
String inputTaken = new String();
while (true) {
String input = scanner.nextLine(); // reading one line of input
if (input.matches("\\s+")) // if it matches spaces/tabs, stop reading
break;
inputTaken += input + " ";
}
System.out.println(inputTaken);
L'oggetto scanner è inizializzato per leggere l'input dalla tastiera. Quindi per l'input qui sotto da keyboar, produrrà l'output come Reading from keyboard
Reading
from
keyboard
//space
Lettura dell'input di file tramite Scanner
Scanner scanner = null;
try {
scanner = new Scanner(new File("Names.txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (Exception e) {
System.err.println("Exception occurred!");
} finally {
if (scanner != null)
scanner.close();
}
Qui viene creato un oggetto Scanner
passando un oggetto File
contenente il nome di un file di testo come input. Questo file di testo verrà aperto dall'oggetto File e letto dall'oggetto scanner nelle seguenti righe. scanner.hasNext()
controllerà per vedere se c'è una riga successiva di dati nel file di testo. La combinazione di questo con un ciclo while
ti consentirà di scorrere ogni riga di dati nel file Names.txt
. Per recuperare i dati stessi, possiamo usare metodi come nextLine()
, nextInt()
, nextBoolean()
, ecc. Nell'esempio sopra, scanner.nextLine()
viene utilizzato. nextLine()
riferisce alla seguente riga in un file di testo e combinandola con un oggetto scanner
consente di stampare il contenuto della linea. Per chiudere un oggetto scanner, dovresti usare .close()
.
Usando try with resources (da Java 7 in poi), il codice sopra citato può essere scritto elegantemente come sotto.
try (Scanner scanner = new Scanner(new File("Names.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (Exception e) {
System.err.println("Exception occurred!");
}
Leggi l'intero input come una stringa usando Scanner
È possibile utilizzare Scanner
per leggere tutto il testo nell'input come String, utilizzando \Z
(intero input) come delimitatore. Ad esempio, questo può essere usato per leggere tutto il testo in un file di testo in una riga:
String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
System.out.println(content);
Ricorda che dovrai chiudere lo Scanner, così come catturare l' IoException
questo può lanciare, come descritto nell'esempio di lettura dell'ingresso del file usando Scanner .
Utilizzando delimitatori personalizzati
È possibile utilizzare delimitatori personalizzati (espressioni regolari) con Scanner, con .useDelimiter(",")
, per determinare come viene letto l'input. Funziona in modo simile a String.split(...)
. Ad esempio, è possibile utilizzare Scanner
per leggere da un elenco di valori separati da virgola in una stringa:
Scanner scanner = null;
try{
scanner = new Scanner("i,like,unicorns").useDelimiter(",");;
while(scanner.hasNext()){
System.out.println(scanner.next());
}
}catch(Exception e){
e.printStackTrace();
}finally{
if (scanner != null)
scanner.close();
}
Questo ti permetterà di leggere ogni elemento nell'input individualmente. Si noti che non si dovrebbe usare questo per analizzare i dati CSV, invece, utilizzare un adeguato libreria parser CSV, vedere CSV parser per Java per altre possibilità.
Schema generale che viene generalmente richiesto per le attività
Di seguito è riportato come utilizzare correttamente la classe java.util.Scanner
per leggere in modo interattivo l'input dell'utente da System.in
correttamente (a volte indicato come stdin
, in particolare in C, C ++ e altri linguaggi nonché in Unix e Linux). Dimostra in modo idiomatico le cose più comuni che devono essere fatte.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* @param s possible url
* @return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(@Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(@Nonnull final String format, @Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying Readable, in this case System.in, and free those resources.
You will not be to read from System.in anymore after this you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
Leggi un int dalla riga di comando
import java.util.Scanner;
Scanner s = new Scanner(System.in);
int number = s.nextInt();
Se vuoi leggere un int dalla riga di comando, usa questo snippet. Prima di tutto, devi creare un oggetto Scanner, che ascolti System.in, che è di default la riga di comando, quando avvii il programma dalla riga di comando. Successivamente, con l'aiuto dell'oggetto Scanner, si legge la prima int che l'utente passa alla riga di comando e la memorizza nel numero variabile. Ora puoi fare tutto ciò che vuoi con quello memorizzato int.
Chiusura accurata di uno scanner
può succedere che si usi uno scanner con System.in come parametro per il costruttore, quindi è necessario essere consapevoli che chiudendo lo scanner si chiuderà anche InputStream dando come prossimo ogni tentativo di leggere l'input su quello (o qualsiasi altro oggetto scanner) genererà java.util.NoSuchElementException
o java.lang.IllegalStateException
esempio:
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
int x1 = sc1.nextInt();
sc1.close();
// java.util.NoSuchElementException
int x2 = sc2.nextInt();
// java.lang.IllegalStateException
x2 = sc1.nextInt();