Java: Jak uzyskać dane wejściowe z System.console ()


162

Próbuję użyć klasy Console, aby uzyskać dane wejściowe od użytkownika, ale obiekt o wartości null jest zwracany, gdy wywołuję System.console() . Czy muszę coś zmieniać przed użyciem System.console?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}

1
czy to jest dla Androida? (zgaduję na podstawie twojego identyfikatora użytkownika)
Ryan Fernandes

Czy używasz eclipse do uruchamiania programu? Spróbuj uruchomić program bez zaćmienia za pomocą java.exe.
keuleJ

5
Spójrz na projekt McDowella „AbstractingTheJavaConsole”: nielegalnyargumentexception.googlecode.com/svn/trunk/code/java/…
athspk

7
@RyanFernandes Jak jego imię ma związek z jego pytaniem?
b1nary.atr0phy

Odpowiedzi:


238

Używanie konsoli do odczytu danych wejściowych (możliwe do użytku tylko poza IDE):

System.out.print("Enter something:");
String input = System.console().readLine();

Inny sposób (działa wszędzie):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException { 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter String");
        String s = br.readLine();
        System.out.print("Enter Integer:");
        try {
            int i = Integer.parseInt(br.readLine());
        } catch(NumberFormatException nfe) {
            System.err.println("Invalid Format!");
        }
    }
}

System.console () zwraca wartość null w środowisku IDE.
Jeśli więc naprawdę potrzebujesz System.console(), przeczytaj to rozwiązanie od McDowell .


dlaczego potrzebujemy BufferedReader do odczytania danych wejściowych dlaczego nie możemy odczytać bezpośrednio z InputStreamReader
Learner

2
Mam odpowiedź: w przypadku BufferedInputStream metoda deleguje do przeciążonej metody read (), która odczytuje 8192 ilości bajtów i buforuje je do momentu, gdy będą potrzebne. Nadal zwraca tylko jeden bajt (ale zachowuje pozostałe w rezerwie). W ten sposób BufferedInputStream wykonuje mniej natywnych wywołań systemu operacyjnego w celu odczytania z pliku. Dzięki
Learner

W przypadku, gdy chcemy odczytać hasło od użytkownika, stackoverflow.com/questions/22545603/ ... maskuje linię gwiazdką.
oraclesoon

@Learner Innym powodem może być to, że BufferedReader udostępnia metodę, readLine()która nie istnieje dla InputStreamReader.
Marcono1234

116
Scanner in = new Scanner(System.in);

int i = in.nextInt();
String s = in.next();

4
Jednak nextLine()praca z nim jest bardzo kłopotliwa. W najlepszym przypadku przy próbie pobrania całych linii z konsoli przyprawi Cię o ból głowy.
Yokhen

9
@Yokhen, czy mógłbyś podać przykład, gdzie in.nextLine()może powstać problem?
ajay

2
(1) Domyślnie ogranicznikiem Scanner jest spacja, więc gdy użytkownik wprowadzi wiele tekstów, spowoduje to przejście oprogramowania do kilku następnych (), a logika w naszym oprogramowaniu będzie błędna. (2) Jeśli użyję nextLine () do odczytania całego zdania, w tym spacji i \ n \ r, muszę przyciąć () dane wejściowe użytkownika. (3) next () będzie czekać na wejście użytkownika, ale nextLine () nie. (4) Przetestowałem useDelimiter ("\\ r \\ n"), ale powoduje to, że logika next () w naszym oprogramowaniu w innym miejscu znowu jest błędna. Podsumowując, używanie Scannera do odczytywania danych wprowadzanych przez użytkownika jest rzeczywiście dość kłopotliwe. BufferedReader jest najlepszy.
oraclesoon

Mam też problemy ze skanerem, w szczególności otrzymuję komunikat java.util.NoSuchElementException, którego nie do końca rozumiem.
Romain Vincent

Wszystko to powinno znajdować się wewnątrz try-with-resources, a metoda powinna być in.nextLine (), jeśli chcesz odczytać wiersz.
Calabacin

35

Istnieje kilka sposobów na odczytanie ciągu wejściowego z konsoli / klawiatury. Poniższy przykładowy kod pokazuje, jak odczytać ciąg z konsoli / klawiatury przy użyciu języka Java.

public class ConsoleReadingDemo {

public static void main(String[] args) {

    // ====
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Please enter user name : ");
    String username = null;
    try {
        username = reader.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("You entered : " + username);

    // ===== In Java 5, Java.util,Scanner is used for this purpose.
    Scanner in = new Scanner(System.in);
    System.out.print("Please enter user name : ");
    username = in.nextLine();      
    System.out.println("You entered : " + username);


    // ====== Java 6
    Console console = System.console();
    username = console.readLine("Please enter user name : ");   
    System.out.println("You entered : " + username);

}
}

Ostatnia część kodu wykorzystała java.io.Consoleklasę. nie można pobrać instancji konsoli System.console()podczas uruchamiania kodu demonstracyjnego przez Eclipse. Ponieważ eclipse uruchamia aplikację jako proces w tle, a nie jako proces najwyższego poziomu z konsolą systemową.


18

Będzie to zależeć od twojego środowiska. Jeśli na przykład używasz Swing UI przez javaw, nie ma konsoli do wyświetlenia. Jeśli pracujesz w środowisku IDE, będzie to bardzo zależało od obsługi IO konsoli przez określone IDE.

Z wiersza poleceń powinno być dobrze. Próba:

import java.io.Console;

public class Test {

    public static void main(String[] args) throws Exception {
        Console console = System.console();
        if (console == null) {
            System.out.println("Unable to fetch console");
            return;
        }
        String line = console.readLine();
        console.printf("I saw this line: %s", line);
    }
}

Uruchom to tylko z java:

> javac Test.java
> java Test
Foo  <---- entered by the user
I saw this line: Foo    <---- program output

Inną opcją jest użycie System.in, które możesz chcieć zawinąć w BufferedReaderaby przeczytać wiersze, lub użyć Scanner(ponownie zawijanie System.in).


7

Znalazłem tutaj dobrą odpowiedź dotyczącą czytania z konsoli, tutaj inny sposób użyj `` Skanera '' do czytania z konsoli:

import java.util.Scanner;
String data;

Scanner scanInput = new Scanner(System.in);
data= scanInput.nextLine();

scanInput.close();            
System.out.println(data);

1
W takim przypadku możesz nie chcieć wywoływać close()skanera, ponieważ spowoduje to zamknięcie System.in i uniemożliwi aplikacji odczytanie go później. (Czytanie później generuje błąd „nie znaleziono linii”)
Trevor

Tak, zgadzam się na to, close () nie należy używać, jeśli intencją jest użycie System.in w dalszej części programu.
akhouri,

5

Spróbuj tego. mam nadzieję, że to pomoże.

    String cls0;
    String cls1;

    Scanner in = new Scanner(System.in);  
    System.out.println("Enter a string");  
    cls0 = in.nextLine();  

    System.out.println("Enter a string");  
    cls1 = in.nextLine(); 

3

Poniższy tekst przyjmuje odpowiedź athspk i tworzy z niej pętlę, która zapętla się, dopóki użytkownik nie wpisze „exit”. Napisałem również dodatkową odpowiedź, w której wziąłem ten kod i umożliwiłem jego przetestowanie.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class LoopingConsoleInputExample {

   public static final String EXIT_COMMAND = "exit";

   public static void main(final String[] args) throws IOException {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("Enter some text, or '" + EXIT_COMMAND + "' to quit");

      while (true) {

         System.out.print("> ");
         String input = br.readLine();
         System.out.println(input);

         if (input.length() == EXIT_COMMAND.length() && input.toLowerCase().equals(EXIT_COMMAND)) {
            System.out.println("Exiting.");
            return;
         }

         System.out.println("...response goes here...");
      }
   }
}

Przykładowe dane wyjściowe:

Enter some text, or 'exit' to quit
> one
one
...response goes here...
> two
two
...response goes here...
> three
three
...response goes here...
> exit
exit
Exiting.

3

Napisałem bibliotekę Text-IO , która radzi sobie z problemem braku System.console () podczas uruchamiania aplikacji w środowisku IDE.

Wprowadza warstwę abstrakcji podobną do tej zaproponowanej przez McDowella . Jeśli System.console () zwróci wartość null, biblioteka przełączy się na konsolę Swing.

Ponadto Text-IO ma szereg przydatnych funkcji:

  • obsługuje odczytywanie wartości z różnymi typami danych.
  • umożliwia maskowanie wejścia podczas odczytu danych wrażliwych.
  • umożliwia wybór wartości z listy.
  • umożliwia określenie ograniczeń wartości wejściowych (wzorce formatu, zakresy wartości, ograniczenia długości itp.).

Przykład użycia:

TextIO textIO = TextIoFactory.getTextIO();

String user = textIO.newStringInputReader()
        .withDefaultValue("admin")
        .read("Username");

String password = textIO.newStringInputReader()
        .withMinLength(6)
        .withInputMasking(true)
        .read("Password");

int age = textIO.newIntInputReader()
        .withMinVal(13)
        .read("Age");

Month month = textIO.newEnumInputReader(Month.class)
        .read("What month were you born in?");

textIO.getTextTerminal().println("User " + user + " is " + age + " years old, " +
        "was born in " + month + " and has the password " + password + ".");

Na tym obrazku możesz zobaczyć powyższy kod działający w konsoli opartej na Swing.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.