Java: So erhalten Sie Eingaben von System.console ()

163

Ich versuche, die Konsolenklasse zu verwenden, um Eingaben vom Benutzer zu erhalten, aber beim Aufruf wird ein Nullobjekt zurückgegeben System.console(). Muss ich etwas ändern, bevor ich System.console verwende?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}
satheesh.droid
quelle
1
ist das für Android? (Ich vermute von Ihrer Benutzer-ID)
Ryan Fernandes
Verwenden Sie Eclipse, um Ihr Programm zu starten? Versuchen Sie, Ihr Programm ohne Eclipse mit java.exe zu starten.
KeuleJ
5
Schauen Sie sich das McDowell-Projekt "AbstractingTheJavaConsole" an: illegalargumentexception.googlecode.com/svn/trunk/code/java/…
athspk
7
@ RyanFernandes Wie ist sein Name für seine Frage relevant?
b1nary.atr0phy

Antworten:

239

Verwenden der Konsole zum Lesen von Eingaben (nur außerhalb einer IDE verwendbar):

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

Ein anderer Weg (funktioniert überall):

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 () gibt in einer IDE null zurück.
Wenn Sie es also wirklich brauchen System.console(), lesen Sie diese Lösung von McDowell .

athspk
quelle
Warum brauchen wir BufferedReader, um die Eingabe zu lesen? Warum können wir nicht direkt von InputStreamReader
Learner
2
Erhielt die Antwort: Mit einem BufferedInputStream delegiert die Methode an eine überladene read () -Methode, die 8192 Bytes liest und sie puffert, bis sie benötigt werden. Es wird immer noch nur das einzelne Byte zurückgegeben (die anderen bleiben jedoch in Reserve). Auf diese Weise ruft der BufferedInputStream weniger native Aufrufe des Betriebssystems auf, um aus der Datei zu lesen. Danke
Lernender
Wenn wir das Passwort vom Benutzer lesen möchten, maskiert stackoverflow.com/questions/22545603/… die Zeile mit einem Sternchen.
Orakel am
@Learner Ein weiterer Grund könnte sein, dass BufferedReader die Methode bereitstellt, für readLine()die es keine gibt InputStreamReader.
Marcono1234
116
Scanner in = new Scanner(System.in);

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

quelle
4
Es nextLine()ist jedoch sehr chaotisch, damit zu arbeiten. Bestenfalls bereitet es Ihnen Kopfschmerzen, wenn Sie versuchen, ganze Zeilen von der Konsole zu holen.
Yokhen
9
@ Yokhen könnten Sie bitte ein Beispiel geben, wo in.nextLine()Probleme entstehen würden?
Ajay
2
(1) Standardmäßig ist das Trennzeichen des Scanners ein Leerzeichen. Wenn der Benutzer mehrere Texte eingibt, führt dies dazu, dass die Software mit den nächsten Nächsten fortfährt () und die Logik in unserer Software falsch ist. (2) Wenn ich nextLine () verwende, um den gesamten vollständigen Satz einschließlich Leerzeichen und \ n \ r zu lesen, muss ich Benutzereingaben kürzen (). (3) next () wartet auf Benutzereingaben, nextLine () jedoch nicht. (4) Ich habe useDelimiter ("\\ r \\ n") getestet, aber es führt dazu, dass die next () - Logik in unserer Software an einer anderen Stelle wieder falsch ist. Fazit: Es ist in der Tat ziemlich chaotisch, Scanner zum Lesen von Benutzereingaben zu verwenden. BufferedReader ist das Beste.
Orakel am
Ich habe auch Probleme mit dem Scanner, insbesondere bekomme ich eine java.util.NoSuchElementException, die ich nicht ganz verstehe.
Romain Vincent
All dies sollte sich in einem Try-with-Resources befinden und die Methode sollte in.nextLine () sein, wenn Sie eine Zeile lesen möchten.
Calabacin
35

Es gibt nur wenige Möglichkeiten, Eingabezeichenfolgen von Ihrer Konsole / Tastatur zu lesen. Der folgende Beispielcode zeigt, wie Sie mit Java eine Zeichenfolge von der Konsole / Tastatur lesen.

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);

}
}

Der letzte Teil des Codes verwendete java.io.ConsoleKlasse. Sie können keine Konsoleninstanz abrufen, System.console()wenn Sie den Demo-Code über Eclipse ausführen. Weil eclipse Ihre Anwendung als Hintergrundprozess und nicht als Prozess der obersten Ebene mit einer Systemkonsole ausführt.

pankaj
quelle
18

Es wird von Ihrer Umgebung abhängen. Wenn Sie javawbeispielsweise eine Swing-Benutzeroberfläche ausführen , ist keine Konsole zum Anzeigen vorhanden. Wenn Sie innerhalb einer IDE ausgeführt werden, hängt dies stark von der Handhabung der Konsolen-E / A durch die jeweilige IDE ab.

Über die Befehlszeile sollte es jedoch in Ordnung sein. Stichprobe:

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);
    }
}

Führen Sie dies nur mit java:

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

Eine andere Option ist die Verwendung System.in, die Sie möglicherweise in BufferedReaderZeilen zum Lesen einfügen oder verwenden möchten Scanner(erneut umbrechen System.in).

Jon Skeet
quelle
7

Hier finden Sie eine gute Antwort zum Lesen von der Konsole. Hier können Sie auf andere Weise mit 'Scanner' von der Konsole lesen:

import java.util.Scanner;
String data;

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

scanInput.close();            
System.out.println(data);
Akhouri
quelle
1
close()In diesem Fall möchten Sie den Scanner möglicherweise nicht aufrufen , da er System.in schließt und Ihre Anwendung später daran hindert, daraus zu lesen. (Lesen später wirft Fehler "keine Zeile gefunden")
Trevor
Ja, ich stimme dem zu, close () sollte nicht verwendet werden, wenn System.in später im Programm verwendet werden soll.
Akhouri
5

Versuche dies. hoffe das wird helfen.

    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(); 

quelle
3

Das Folgende nimmt die Antwort von athspk und macht sie zu einer Antwort , die sich kontinuierlich wiederholt , bis der Benutzer "exit" eingibt . Ich habe auch eine Antwort geschrieben, in der ich diesen Code genommen und testbar gemacht habe.

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...");
      }
   }
}

Beispielausgabe:

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.
aliteralmind
quelle
3

Ich habe die Text-IO- Bibliothek geschrieben, die das Problem lösen kann, dass System.console () null ist, wenn eine Anwendung in einer IDE ausgeführt wird.

Es wird eine Abstraktionsschicht eingeführt, die der von McDowell vorgeschlagenen ähnelt . Wenn System.console () null zurückgibt, wechselt die Bibliothek zu einer Swing-basierten Konsole.

Darüber hinaus bietet Text-IO eine Reihe nützlicher Funktionen:

  • unterstützt das Lesen von Werten mit verschiedenen Datentypen.
  • Ermöglicht das Maskieren der Eingabe beim Lesen sensibler Daten.
  • ermöglicht die Auswahl eines Wertes aus einer Liste.
  • Ermöglicht die Angabe von Einschränkungen für die Eingabewerte (Formatmuster, Wertebereiche, Längenbeschränkungen usw.).

Anwendungsbeispiel:

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 + ".");

In diesem Bild sehen Sie den obigen Code, der in einer Swing-basierten Konsole ausgeführt wird.

Siordache
quelle