Comment lire une entrée standard ligne par ligne?


91

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

Réponses:


130

L'approche la plus simple utilisera simplement readLine()ce 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 que vous préférez utiliser à la java.util.Scannerplace.

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

3
la méthode readLine de Predef est obsolète depuis la 2.11.0, il est maintenant recommandé d'utiliser la méthode dansscala.io.StdIn
— nicolastrres

1
@itemState mon programme ne se termine pas, si j'utilise, "io.Source.stdin.getLines" passe en mode attente ... comment gérer cela ...
— Raja

53

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

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

Je connais Console.readLine (), je recherche une recette donnée. La méthode "scala" pour lire ligne par ligne à partir de l'entrée Standard.
— Andrei Ciobanu

11
Je pense que vous voulez diretakeWhile(_ != null)
— Seth Tisue

1
Cela dépend de la façon dont vous voulez vous arrêter. La recherche d'une ligne vide est souvent la solution la plus simple.
— Landei le

4
Notez que de Scala 2.11.0 Console.readLineest obsolète, utilisez à la StdIn.readlineplace.
— Bartłomiej Szałach

Ou .takeWhile(Option(_).nonEmpty)vous vous sentirez peut-être mieux au cas où vous voudriez éviter nullcomplètement le mot - clé.
— conny

27
val input = Source.fromInputStream(System.in);
val lines = input.getLines.collect

6
io.Source.stdinest défini (en scala.io.Sourceclasse) comme il est def stdin = fromInputStream(System.in)donc probablement préférable de s'en tenir au io.Source.stdin.
— Nader Ghanbari

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

Cela fonctionne dans Scala 2.12, juste que la collectméthode soit modifiée sicne cette réponse donc vous devez simplement appeler input.getLinesce qui vous donne un Iterator. Vous pouvez le forcer à se matérialiser en utilisant .toStreamou .toListdessus, selon le cas d'utilisation.
— Nader Ghanbari

11

Une version récursive (le compilateur détecte une récursivité de queue pour une meilleure utilisation du tas),

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

Notez l'utilisation de io.StdInde Scala 2.11. Notez également qu'avec cette approche, nous pouvons accumuler les entrées 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]())
}

10

Ne peux-tu pas utiliser

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

Disponible ici: API Scaladoc


ce n'est pas équivalent au code présenté avec boucle
— techkuz

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.