Java Language
Skaner
Szukaj…
Składnia
- Skaner skaner = nowy skaner (źródło);
- Skaner skaner = nowy skaner (System.in);
Parametry
Parametr | Detale |
---|---|
Źródło | Źródłem może być String, File lub dowolny rodzaj InputStream |
Uwagi
Klasa Scanner
została wprowadzona w Javie 5. W Javie 6 dodano metodę reset()
, a w Javie 7 dodano kilka nowych konstruktorów w celu zapewnienia interoperacyjności z (wówczas) nowym interfejsem Path
.
Odczytywanie danych wejściowych systemu za pomocą skanera
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);
Obiekt skanera jest inicjowany w celu odczytu danych wejściowych z klawiatury. Tak więc dla poniższych danych wejściowych z keyboar, wygeneruje dane wyjściowe jako Reading from keyboard
Reading
from
keyboard
//space
Odczytywanie danych wejściowych pliku za pomocą skanera
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();
}
Tutaj tworzony jest obiekt Scanner
przekazując jako dane wejściowe obiekt File
zawierający nazwę pliku tekstowego. Ten plik tekstowy zostanie otwarty przez obiekt File i wczytany przez obiekt skanera w następujących wierszach. scanner.hasNext()
sprawdzi, czy w pliku tekstowym jest następny wiersz danych. Łącząc to z while
pętli pozwoli Ci wykonać iterację każdego wiersza danych w Names.txt
pliku. Aby pobrać same dane, możemy użyć metod takich jak nextLine()
, nextInt()
, nextBoolean()
itp. W powyższym przykładzie scanner.nextLine()
. nextLine()
odnosi się do następującego wiersza w pliku tekstowym, a połączenie go z obiektem scanner
pozwala wydrukować zawartość wiersza. Aby zamknąć obiekt skanera, użyj .close()
.
Używając try z zasobami (od Java 7 wzwyż), wyżej wspomniany kod można napisać elegancko, jak poniżej.
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!");
}
Przeczytaj cały wpis jako ciąg znaków za pomocą skanera
Możesz użyć Scanner
aby odczytać cały tekst na wejściu jako ciąg, używając \Z
(całe wejście) jako separatora. Na przykład można tego użyć do odczytania całego tekstu w pliku tekstowym w jednym wierszu:
String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
System.out.println(content);
Pamiętaj, że musisz zamknąć skaner, a także złapać IoException
może to wyrzucić, jak opisano w przykładzie Odczytywanie pliku wejściowego za pomocą skanera .
Korzystanie z niestandardowych ograniczników
Możesz użyć niestandardowych ograniczników (wyrażeń regularnych) ze skanerem, używając .useDelimiter(",")
, aby określić sposób odczytu danych wejściowych. Działa to podobnie do String.split(...)
. Na przykład możesz użyć Scanner
aby odczytać z listy wartości oddzielonych przecinkami w ciągu:
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();
}
Umożliwi to indywidualne odczytanie każdego elementu na wejściu. Zauważ, że nie powinieneś tego używać do analizowania danych CSV, zamiast tego użyj odpowiedniej biblioteki parserów CSV, zobacz parser CSV dla Javy, aby poznać inne możliwości.
Ogólny wzorzec, który najczęściej pyta o zadania
Poniżej opisano, jak prawidłowo używać klasy java.util.Scanner
do interaktywnego odczytu danych wejściowych użytkownika z System.in
(czasami nazywanych stdin
, szczególnie w C, C ++ i innych językach, a także w systemach Unix i Linux). Idiomatycznie pokazuje najczęstsze rzeczy, które należy wykonać.
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);
}
}
Przeczytaj int z wiersza poleceń
import java.util.Scanner;
Scanner s = new Scanner(System.in);
int number = s.nextInt();
Jeśli chcesz odczytać wartość int z wiersza poleceń, użyj tego fragmentu kodu. Przede wszystkim musisz utworzyć obiekt skanera, który nasłuchuje System.in, który jest domyślnie wierszem poleceń, podczas uruchamiania programu z wiersza poleceń. Następnie za pomocą obiektu Scanner odczytujesz pierwszą wartość, którą użytkownik przechodzi do linii poleceń i zapisujesz ją pod numerem zmiennej. Teraz możesz robić, co chcesz, z tego przechowywanego int.
Ostrożnie zamykaj skaner
może się zdarzyć, że użyjesz skanera z System.in jako parametrem dla konstruktora, wtedy musisz mieć świadomość, że zamknięcie skanera spowoduje zamknięcie InputStream również podając jako następną każdą próbę odczytania danych wejściowych na nim (lub innym obiekt skanera) zgłosi java.lang.IllegalStateException
java.util.NoSuchElementException
lub java.lang.IllegalStateException
przykład:
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();