Как читать стандартный ввод строки за строкой?
Что рецепт 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
Самый простой подход просто использует readLine()
, который является частью Predef
. однако это довольно уродливо, так как вам нужно проверить возможное нулевое значение:
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)
}
}
Ответ 2
Для консоли вы можете использовать Console.readLine
. Вы можете написать (если вы хотите остановиться на пустой строке):
Iterator.continually(Console.readLine).takeWhile(_.nonEmpty).foreach(line => println("read " + line))
Если вы создаете файл для генерации ввода, вам может потребоваться остановить либо нулевой, либо пустой, используя:
@inline def defined(line: String) = {
line != null && line.nonEmpty
}
Iterator.continually(Console.readLine).takeWhile(defined(_)).foreach(line => println("read " + line))
Ответ 3
val input = Source.fromInputStream(System.in);
val lines = input.getLines.collect
Ответ 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
}
Обратите внимание на использование io.StdIn
из Scala 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]())
}