Java: comment obtenir une entrée de System.console ()

162

J'essaie d'utiliser la classe Console pour obtenir l'entrée de l'utilisateur mais un objet nul est renvoyé lorsque j'appelle System.console(). Dois-je modifier quelque chose avant d'utiliser System.console?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}
satheesh.droid
la source
1
est-ce pour Android? (Je suppose à partir de votre identifiant d'utilisateur)
Ryan Fernandes
Utilisez-vous eclipse pour démarrer votre programme? Essayez de démarrer votre programme sans éclipse en utilisant java.exe.
keuleJ
5
Jetez un œil au projet de McDowell "AbstractingTheJavaConsole": illegalargumentexception.googlecode.com/svn/trunk/code/java/…
athspk
7
@RyanFernandes En quoi son nom est-il pertinent par rapport à sa question?
b1nary.atr0phy

Réponses:

238

Utilisation de la console pour lire l'entrée (utilisable uniquement en dehors d'un IDE):

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

Une autre façon (fonctionne partout):

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 () renvoie null dans un IDE.
Donc, si vous avez vraiment besoin d'utiliser System.console(), lisez cette solution de McDowell .

athspk
la source
pourquoi nous avons besoin de BufferedReader pour lire l'entrée pourquoi ne pouvons-nous pas lire directement à partir d'InputStreamReader
Apprenant
2
Vous avez la réponse: avec un BufferedInputStream, la méthode délègue à une méthode read () surchargée qui lit 8192 octets et les met en mémoire tampon jusqu'à ce qu'ils soient nécessaires. Il ne renvoie toujours que l'octet unique (mais garde les autres en réserve). De cette façon, BufferedInputStream effectue moins d'appels natifs au système d'exploitation pour lire le fichier. Merci
Apprenant
Si nous voulons lire le mot de passe de l'utilisateur, stackoverflow.com/questions/22545603/… masque la ligne avec un astérisque.
oraclesoon
@Learner une autre raison pourrait être que BufferedReader fournit la méthode readLine()qui n'existe pas pour InputStreamReader.
Marcono1234
116
Scanner in = new Scanner(System.in);

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

la source
4
Cependant, il nextLine()est très compliqué de travailler avec. Au mieux, cela vous donnera mal à la tête lorsque vous essayez d'obtenir des lignes entières de la console.
Yokhen
9
@Yokhen pourriez-vous s'il vous plaît donner un exemple où in.nextLine()créerait des problèmes?
ajay
2
(1) Par défaut, le délimiteur du scanner est un espace, donc lorsque l'utilisateur entre plusieurs textes, le logiciel passera aux prochains suivants () et la logique de notre logiciel sera erronée. (2) Si j'utilise nextLine () pour lire toute la phrase, y compris l'espace et \ n \ r, j'ai besoin de l'entrée utilisateur trim (). (3) next () attendra l'entrée de l'utilisateur mais nextLine () ne le fera pas. (4) J'ai testé useDelimiter ("\\ r \\ n"), mais la logique next () de notre logiciel est à nouveau erronée. Conclusion, il est en effet assez compliqué d'utiliser Scanner pour lire les entrées utilisateur. BufferedReader est le meilleur.
oraclesoon
J'ai aussi des problèmes avec le scanner, notamment j'obtiens un java.util.NoSuchElementExceptionque je ne comprends pas très bien.
Romain Vincent
Tout cela devrait être à l'intérieur d'un try-with-resources et la méthode devrait être in.nextLine () si vous voulez lire une ligne.
Calabacin
35

Il existe plusieurs façons de lire la chaîne d'entrée depuis votre console / clavier. L'exemple de code suivant montre comment lire une chaîne à partir de la console / du clavier à l'aide de 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);

}
}

La dernière partie du code utilisée java.io.Consoleclasse. vous ne pouvez pas obtenir d'instance de console System.console()lors de l'exécution du code de démonstration via Eclipse. Parce qu'eclipse exécute votre application en tant que processus d'arrière-plan et non en tant que processus de niveau supérieur avec une console système.

Pankaj
la source
18

Cela dépendra de votre environnement. Si vous exécutez une interface utilisateur Swing via, javawpar exemple, il n'y a pas de console à afficher. Si vous exécutez dans un IDE, cela dépendra beaucoup de la gestion spécifique de l'EDI des E / S de la console.

À partir de la ligne de commande, cela devrait bien se passer. Échantillon:

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

Exécutez ceci simplement avec java:

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

Une autre option consiste à utiliser System.in, que vous voudrez peut-être envelopper dans un BufferedReaderpour lire les lignes, ou utiliser Scanner(encore une fois System.in).

Jon Skeet
la source
7

J'ai trouvé une bonne réponse ici concernant la lecture depuis la console, voici une autre façon d'utiliser 'Scanner' pour lire depuis la console:

import java.util.Scanner;
String data;

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

scanInput.close();            
System.out.println(data);
Akhouri
la source
1
Vous ne voudrez peut-être pas appeler close()le scanner dans ce cas, car il fermera System.in et empêchera votre application de le lire plus tard. (La lecture plus tard génère l'erreur "aucune ligne trouvée")
Trevor
Oui, j'accepte cela, close () ne doit pas être utilisé si l'intention est d'utiliser System.in plus tard dans le programme.
akhouri
5

Essaye ça. espérons que cela aidera.

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

la source
3

Ce qui suit prend la réponse d'athspk et en fait une qui boucle continuellement jusqu'à ce que l'utilisateur tape "exit". J'ai également écrit une réponse de suivi dans laquelle j'ai pris ce code et l'ai rendu testable.

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

Exemple de sortie:

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
la source
3

J'ai écrit la bibliothèque Text-IO , qui peut gérer le problème de la nullité de System.console () lors de l'exécution d'une application à partir d'un IDE.

Il introduit une couche d'abstraction similaire à celle proposée par McDowell . Si System.console () renvoie null, la bibliothèque bascule vers une console basée sur Swing.

De plus, Text-IO possède une série de fonctionnalités utiles:

  • prend en charge la lecture de valeurs avec différents types de données.
  • permet de masquer l'entrée lors de la lecture de données sensibles.
  • permet de sélectionner une valeur dans une liste.
  • permet de spécifier des contraintes sur les valeurs d'entrée (modèles de format, plages de valeurs, contraintes de longueur, etc.).

Exemple d'utilisation:

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

Dans cette image, vous pouvez voir le code ci-dessus s'exécuter dans une console basée sur Swing.

siordache
la source