2011-01-03 41 views
86

¿Cuál es la receta de Scala para leer línea por línea desde la entrada estándar? Algo así como el código java equivalente:¿Cómo leer desde la entrada estándar línea por línea?

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

Respuesta

126

El enfoque más directo solo usará readLine() que es parte de Predef. sin embargo, que es bastante feo como sea necesario para comprobar la eventual valor nulo:

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

esto es tan prolijo, prefiere utilizar java.util.Scanner lugar.

creo que un enfoque más bonita utilizará scala.io.Source:

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

Para la consola puede usar Console.readLine. Se puede escribir (si desea detener en una línea vacía):

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

Si gato un archivo para generar la entrada es posible que tenga que parar en cualquiera nulo o vacío usando:

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

Sé lo de Console.readLine(), estoy buscando una receta dada. La forma "scala" para leer línea por línea desde entrada estándar. –

+10

Creo que quieres decir 'takeWhile (_! = Null)' –

+1

Depende de cómo quieras detenerlo. Buscar una línea vacía suele ser la solución más simple. – Landei

26
val input = Source.fromInputStream(System.in); 
val lines = input.getLines.collect 
+3

'io.Source.stdin' se define (en la clase' scala.io.Source') como 'def stdin = fromInputStream (System.in)' por lo que probablemente sea mejor seguir con 'io.Source.stdin'. –

+0

Esto no parece funcionar con Scala 2.12.4, o no encontré las cosas correctas para importar. – akauppi

10

¿Puede usted no utilizar

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

Como disponible aquí: Scaladoc API

7

Una versión recursiva (el compilador detecta una cola recursión para un uso mejorado del montón),

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

Tenga en cuenta el uso de io.StdIn de Scala 2.11. También tenga en cuenta que con este enfoque podemos acumular la entrada del usuario en una colección que finalmente se devuelve, además de imprimirse. A saber,

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]()) 
} 
Cuestiones relacionadas