Comment lire à partir d'entrée standard ligne par ligne?

Quelle est la recette Scala pour lire ligne par ligne à partir de 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());
        }
    }
}
88
demandé sur Jacek Laskowski 2011-01-03 18:18:17

5 réponses

L'approche la plus simple utilisera simplement readLine() qui fait partie de Predef. cependant, c'est plutôt moche car vous devez vérifier la valeur nulle éventuelle:

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, 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)
  }
}
128
répondu itemState 2013-11-15 16:55:49

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 votre chat un fichier pour générer l'entrée, vous devrez peut-être arrêter sur null ou vide utilisation:

@inline def defined(line: String) = {
  line != null && line.nonEmpty
}
Iterator.continually(Console.readLine).takeWhile(defined(_)).foreach(line => println("read " + line))
52
répondu Landei 2014-06-20 14:13:30
val input = Source.fromInputStream(System.in);
val lines = input.getLines.collect
27
répondu Jason 2011-01-03 15:37:08

Ne pouvez-vous pas utiliser

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

Comme disponible ici: API Scaladoc

10
répondu kaning 2011-12-15 15:30:08

Une version récursive (le compilateur détecte une récursion de queue pour une utilisation améliorée du tas),

def read: Unit = {
  val s = scala.io.StdIn.readLine()
  println(s)
  if (s.isEmpty) () else read 
}

Notez l'utilisation de io.StdIn Scala 2.11 . Notez également avec cette approche, nous pouvons accumuler l'entrée de l'utilisateur dans une collection qui est finalement retournée-en plus d'être imprimée. À savoir,

import annotation.tailrec

def read: Seq[String]= {

  @tailrec
  def reread(xs: Seq[String]): Seq[String] = {
    val s = StdIn.readLine()
    println(s)
    if (s.isEmpty()) xs else reread(s +: xs) 
  }

  reread(Seq[String]())
}
8
répondu elm 2016-04-14 09:23:59