93 votes

Comment lire l'entrée standard ligne par ligne ?

Quelle est la recette Scala pour lire ligne par ligne l'entrée standard ? Quelque chose comme le code java équivalent :

import java.util.Scanner; 

public class ScannerTest {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            System.out.println(sc.nextLine());
        }
    }
}

132voto

itemState Points 656

L'approche la plus simple consistera à utiliser la fonction readLine() qui fait partie de Predef . mais c'est plutôt moche car il faut vérifier si la valeur est nulle :

object ScannerTest {
  def main(args: Array[String]) {
    var ok = true
    while (ok) {
      val ln = readLine()
      ok = ln != null
      if (ok) println(ln)
    }
  }
}

c'est tellement verbeux que vous préférez utiliser java.util.Scanner à la place.

Je pense qu'une approche plus jolie utilisera scala.io.Source :

object ScannerTest {
  def main(args: Array[String]) {
    for (ln <- io.Source.stdin.getLines) println(ln)
  }
}

4 votes

La méthode readLine de Predef a été dépréciée depuis la version 2.11.0, il est maintenant recommandé d'utiliser la méthode en scala.io.StdIn

1 votes

@itemState Mon programme ne se termine pas, si j'utilise "io.Source.stdin.getLines", il passe en mode attente ... comment gérer cela ?

54voto

Landei Points 30509

Pour la console, vous pouvez utiliser Console.readLine . Vous pouvez écrire (si vous voulez vous arrêter sur une ligne vide) :

Iterator.continually(Console.readLine).takeWhile(_.nonEmpty).foreach(line => println("read " + line))

Si vous capturez un fichier pour générer l'entrée, vous devrez peut-être vous arrêter sur l'utilisation de null ou de vide :

@inline def defined(line: String) = {
  line != null && line.nonEmpty
}
Iterator.continually(Console.readLine).takeWhile(defined(_)).foreach(line => println("read " + line))

0 votes

Je connais Console.readLine(), je cherche une recette donnée . La méthode "scala" pour lire ligne par ligne l'entrée standard .

11 votes

Je pense que vous voulez dire takeWhile(_ != null)

1 votes

Ça dépend de la façon dont vous voulez vous arrêter. Chercher une ligne vide est souvent la solution la plus simple.

27voto

Jason Points 690
val input = Source.fromInputStream(System.in);
val lines = input.getLines.collect

6 votes

io.Source.stdin est défini (dans scala.io.Source ) en tant que def stdin = fromInputStream(System.in) il est donc probablement préférable de s'en tenir à l'option io.Source.stdin .

0 votes

Cela ne semble pas fonctionner avec Scala 2.12.4, ou alors je n'ai pas trouvé les bons éléments à importer.

0 votes

Cela fonctionne dans Scala 2.12, juste que la fonction collect a été modifiée dans cette réponse, vous devez donc appeler la méthode input.getLines qui vous donne un Iterator . Vous pouvez le forcer à se matérialiser en utilisant .toStream o .toList sur elle, dépend du cas d'utilisation.

10voto

kaning Points 117

Ne pouvez-vous pas utiliser

var userinput = readInt // for integers
var userinput = readLine 
...

Comme disponible ici : API Scaladoc

0 votes

Ce n'est pas équivalent au code présenté avec la boucle

1voto

xagyg Points 4281

Simplifier le premier bloc de code de @itemState (+1) ...

object ScannerTest {
  def main(args: Array[String]) {
    var line;
    while((line = readLine()) != null ) {                 
      println(line)
    }
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X