如何逐行读取标准输入?

Posted

技术标签:

【中文标题】如何逐行读取标准输入?【英文标题】:How to read from standard input line by line? 【发布时间】:2011-06-02 21:47:28 【问题描述】:

从标准输入逐行读取的 Scala 方法是什么?类似于等效的 java 代码:

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

【问题讨论】:

【参考方案1】:

对于控制台,您可以使用Console.readLine。你可以写(如果你想停在一个空行上):

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

如果您使用 cat 文件来生成输入,您可能需要使用以下命令在 null 或空时停止:

@inline def defined(line: String) = 
  line != null && line.nonEmpty

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

【讨论】:

我知道 Console.readLine(),我正在寻找一个给定的食谱。从标准输入逐行读取的“scala”方式。 我想你的意思是takeWhile(_ != null) 取决于您要如何停止。寻找空行通常是最简单的解决方案。 请注意,从 Scala 2.11.0 开始,Console.readLine 已被弃用,请改用 StdIn.readline .takeWhile(Option(_).nonEmpty) 可能会更好,以防您想完全避免使用null 关键字。【参考方案2】:
val input = Source.fromInputStream(System.in);
val lines = input.getLines.collect

【讨论】:

io.Source.stdin 被定义(在scala.io.Source 类中)为def stdin = fromInputStream(System.in),所以最好坚持使用io.Source.stdin 这似乎不适用于 Scala 2.12.4,或者我没有找到要导入的正确内容。 它在 Scala 2.12 中工作,只是 collect 方法在这个答案中发生了变化,所以你只需要调用 input.getLines,它会给你一个 Iterator。您可以使用.toStream.toList 强制它实现,具体取决于用例。【参考方案3】:

最直接的方法就是使用readLine(),它是Predef 的一部分。然而,这相当难看,因为您需要检查最终的 null 值:

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

这太冗长了,你宁愿使用java.util.Scanner

我认为更漂亮的方法是使用scala.io.Source

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

【讨论】:

Predef 的 readLine 方法从 2.11.0 开始被废弃,现在推荐使用scala.io.StdIn中的方法 @itemState 我的程序没有结束,如果我使用,“io.Source.stdin.getLines”将进入等待模式......如何处理......【参考方案4】:

你不能用吗

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

在这里可用:Scaladoc API

【讨论】:

这不等同于带有循环的代码【参考方案5】:

递归版本(编译器检测尾递归以提高堆使用率),

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

注意 Scala 2.11 中 io.StdIn 的使用。另请注意,使用这种方法,我们可以将用户输入累积到最终返回的集合中——除了打印出来。即,

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

【讨论】:

【参考方案6】:

正如在其他 cmets 中简要指出的,scala.Predef.readLine() is deprecated 从 Scala 2.11.0 开始,您可以将其替换为 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 != "")

【讨论】:

以上是关于如何逐行读取标准输入?的主要内容,如果未能解决你的问题,请参考以下文章

如何连续读取标准输入? [复制]

你如何从标准输入读取?

Golang 从标准输入读取,如何检测特殊键(回车、退格...等)

如何从标准输入读取 dask 数据帧?

如何从标准输入读取一行,阻塞直到找到换行符?

如何从 Java 中的标准输入中读取整数值