2011-01-03 10 views
86

Jaki jest przepis Scala na czytanie linii po linii ze standardowego wejścia? Coś jak równoważny kod Java:Jak odczytać ze standardowego wejścia wiersz po linii?

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

Odpowiedz

126

Najprostszym sposobem podejścia będzie po prostu użyć readLine(), który jest częścią Predef. jednak, że to raczej brzydki jak trzeba sprawdzić ewentualną wartość null:

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

tak jest gadatliwy, wolisz używać java.util.Scanner zamiast.

myślę bardziej całkiem podejście użyje scala.io.Source:

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

Do konsoli można użyć Console.readLine. można napisać (jeśli chcesz zatrzymać się na pustym wierszu):

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

Jeśli kot plik do generowania wejściowych może być konieczne, aby zatrzymać się na albo null lub pusty za pomocą:

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

Wiem o Console.readLine(), szukam danego przepisu. "Scala" sposób czytania linii po linii ze standardowego wejścia. –

+10

Myślę, że masz na myśli 'takeWhile (_! = Null)' –

+1

Zależy od tego, jak chcesz się zatrzymać. Poszukiwanie pustej linii jest często najprostszym rozwiązaniem. – Landei

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

'io.Source.stdin' jest zdefiniowany (w klasie' scala.io.Source') jako 'def stdin = fromInputStream (System.in)', więc prawdopodobnie lepiej jest trzymać się 'io.Source.stdin'. –

+0

To nie działa z Scala 2.12.4 lub nie znalazłem odpowiednich rzeczy do zaimportowania. – akauppi

10

Nie możesz używać

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

Jako dostępny tutaj: Scaladoc API

7

rekurencyjna wersja (kompilator wykryje ogon rekurencja dla lepszego wykorzystania sterty),

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

Uwaga na użycie io.StdIn ze Scala 2.11. Należy również zauważyć, że dzięki temu podejściu możemy gromadzić dane wejściowe użytkownika w kolekcji, która jest ostatecznie zwracana - oprócz tego, że zostanie wydrukowana. Mianowicie,

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