標準入力から行ごとに読み取る方法は?


91

標準入力から1行ずつ読み取る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());
        }
    }
}

回答:


130

最も単純な方法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)
  }
}

3
PredefのメソッドreadLineは2.11.0以降非推奨になりました。今では、このメソッドを使用することをお勧めしますscala.io.StdIn
nicolastrres

1
@itemState私のプログラムが終了していない場合、「io.Source.stdin.getLines」が待機モードになります...これをどのように処理するか...
Raja

53

コンソールにはを使用できますConsole.readLine。あなたは書くことができます(空の行で停止したい場合):

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

入力を生成するためにファイルを分類する場合は、次のコマンドを使用してnullまたは空で停止する必要がある場合があります。

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

Console.readLine()について知っています。特定のレシピを探しています。標準入力から1行ずつ読み取る「スカラ」方式。
Andrei Ciobanu、2011年

11
私はあなたが意味すると思いますtakeWhile(_ != null)
セスTisue

1
停止方法によって異なります。多くの場合、空の行を探すことが最も簡単な解決策です。
Landei、2011年

4
Scala 2.11.0以降Console.readLineは非推奨ですStdIn.readline。代わりに使用してください。
パルトロミエSzałach

または.takeWhile(Option(_).nonEmpty)nullキーワードを完全に避けたい場合は、気分が良くなるかもしれません。
18年

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

6
io.Source.stdinは(scala.io.Sourceクラスで)定義されているdef stdin = fromInputStream(System.in)ため、おそらくio.Source.stdin
Nader Ghanbari、2014年

これはScala 2.12.4では機能しないようです。または、インポートする適切なものが見つかりませんでした。
akauppi 2018

これはScala 2.12で動作しcollectますが、メソッドがこの回答に変更されているため、を呼び出すだけinput.getLinesで済みますIterator。あなたは使用して実体化するためにそれを強制することができ.toStreamたり.toList、その上に、ユースケースによって異なります。
Nader Ghanbari、

11

再帰バージョン(コンパイラはヒープの使用を改善するために末尾再帰を検出します)、

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

io.StdInScala 2.11からの使用に注意してください。また、このアプローチを使用すると、ユーザー入力をコレクションに蓄積して、最終的に返される(印刷されるだけでなく)ことができます。つまり、

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

使えない

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

ここで利用可能:Scaladoc API


これはループ付きの提示されたコードと同等ではありません
techkuz

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.