How to read from standard input line by line?

后端 未结 6 577
走了就别回头了
走了就别回头了 2020-12-22 17:19

What\'s the Scala recipe for reading line by line from the standard input ? Something like the equivalent java code :

import java.util.Scanner; 

public cla         


        
相关标签:
6条回答
  • 2020-12-22 17:31
    val input = Source.fromInputStream(System.in);
    val lines = input.getLines.collect
    
    0 讨论(0)
  • 2020-12-22 17:33

    The most straight-forward looking approach will just use readLine() which is part of Predef. however that is rather ugly as you need to check for eventual null value:

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

    this is so verbose, you'd rather use java.util.Scanner instead.

    I think a more pretty approach will use scala.io.Source:

    object ScannerTest {
      def main(args: Array[String]) {
        for (ln <- io.Source.stdin.getLines) println(ln)
      }
    }
    
    0 讨论(0)
  • 2020-12-22 17:33

    A recursive version (the compiler detects a tail recursion for improved heap usage),

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

    Note the use of io.StdIn from Scala 2.11 . Also note with this approach we can accumulate user input in a collection that is eventually returned -- in addition to be printed out. Namely,

    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]())
    }
    
    0 讨论(0)
  • 2020-12-22 17:41

    For the console you can use Console.readLine. You can write (if you want to stop on an empty line):

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

    If you cat a file to generate the input you may need to stop on either null or empty using:

    @inline def defined(line: String) = {
      line != null && line.nonEmpty
    }
    Iterator.continually(Console.readLine).takeWhile(defined(_)).foreach(line => println("read " + line))
    
    0 讨论(0)
  • 2020-12-22 17:43

    Can you not use

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

    As available here : Scaladoc API

    0 讨论(0)
  • 2020-12-22 17:54

    As noted briefly in other comments, scala.Predef.readLine() is deprecated since Scala 2.11.0, and you can replace it with scala.io.StdIn.readLine():

    // Read STDIN lines until a blank one
    import scala.io.StdIn.readLine
    
    var line = ""
    do {
      line = readLine()
      println("Read: " + line)
    } while (line != "")
    
    0 讨论(0)
提交回复
热议问题