在 Kotlin 中读取控制台输入 [英] Reading console input in Kotlin

查看:51
本文介绍了在 Kotlin 中读取控制台输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 Kotlin 中接受来自控制台的输入,但这很困难,因为我对语法不太确定.

I am attempting to accept input from the console in Kotlin but it is difficult because I am not too sure about the syntax.

我从主要的开始

fun main(args: Array<String>) {

}

在这之后我应该输入什么?我知道涉及到 println()readline() 但我不知道如何构造它们.

WHAT should I enter after this? I am aware that the println() and readline() are involved but I do not know how to structure them.

目的:提示用户输入一个数字,输入的数字乘以6,程序将结果返回到控制台显示.

Objective: prompt user to enter a number, the number entered is multiplied by 6, program returns the result to the console display.

推荐答案

以下是 Kotlin 从标准输入读取的 A+B 示例:

Here are A+B examples in Kotlin reading from stdin:

fun main() {
  val (a, b) = readLine()!!.split(' ')
  println(a.toInt() + b.toInt())
}

fun main(vararg args: String) {
  val (a, b) = readLine()!!.split(' ').map(String::toInt)
  println(a + b)
}

fun readInts() = readLine()!!.split(' ').map { it.toInt() }

fun main(vararg args: String) {
  val (a, b) = readInts()
  println(a + b)
}

import java.util.Scanner

fun main() {
  val input = Scanner(System.`in`)
  val a = input.nextInt()
  val b = input.nextInt()
  println(a + b)
}

with(Scanner(System.`in`)) {
    val a = nextInt()
    val b = nextInt()
    println(a + b)
}

<小时>

竞争性编程

必读介绍:https://kotlinlang.org/docs/tutorials/competitive-programming.html

必看的 Kotlin 生产力视频:https://www.jetbrains.com/icpc/

Must-watch Kotlin productivity videos: https://www.jetbrains.com/icpc/

这是一个(受文章启发)扩展的一堆辅助函数,用于读取所有可能的类型、列表、数组、二维数组等:

Here is an (inspired by the article) extended bunch of helper functions for reading all possible types, lists, arrays, 2d-arrays, etc:

private fun readln() = readLine()!!
private fun readlnByte() = readln().toByte()
private fun readlnShort() = readln().toShort()
private fun readlnInt() = readln().toInt()
private fun readlnLong() = readln().toLong()
private fun readlnFloat() = readln().toFloat()
private fun readlnDouble() = readln().toDouble()
private fun readlnBigInt(radix: Int = 10) = readln().toBigInteger(radix)
private fun readlnBigDecimal() = readln().toBigDecimal()

private fun lineSequence(limit: Int = Int.MAX_VALUE) = generateSequence { readLine() }.constrainOnce().take(limit)
private fun readlnStrings() = readln().split(' ')
private fun readlnBytes() = readlnStrings().map { it.toByte() }
private fun readlnShorts() = readlnStrings().map { it.toShort() }
private fun readlnInts() = readlnStrings().map { it.toInt() }
private fun readlnLongs() = readlnStrings().map { it.toLong() }
private fun readlnFloats() = readlnStrings().map { it.toFloat() }
private fun readlnDoubles() = readlnStrings().map { it.toDouble() }

private fun readByteArray() = readlnStrings().run { ByteArray(size) { get(it).toByte() } }
private fun readShortArray() = readlnStrings().run { ShortArray(size) { get(it).toShort() } }
private fun readIntArray() = readlnStrings().run { IntArray(size) { get(it).toInt() } }
private fun readLongArray() = readlnStrings().run { LongArray(size) { get(it).toLong() } }
private fun readFloatArray() = readlnStrings().run { FloatArray(size) { get(it).toFloat() } }
private fun readDoubleArray() = readlnStrings().run { DoubleArray(size) { get(it).toDouble() } }

private fun readlnByteArray(n: Int) = ByteArray(n) { readlnByte() }
private fun readlnShortArray(n: Int) = ShortArray(n) { readlnShort() }
private fun readlnIntArray(n: Int) = IntArray(n) { readlnInt() }
private fun readlnLongArray(n: Int) = LongArray(n) { readlnLong() }
private fun readlnFloatArray(n: Int) = FloatArray(n) { readlnFloat() }
private fun readlnDoubleArray(n: Int) = DoubleArray(n) { readlnDouble() }

private fun readByteArray2d(rows: Int, cols: Int) = Array(rows) { readByteArray().also { require(it.size == cols) } }
private fun readShortArray2d(rows: Int, cols: Int) = Array(rows) { readShortArray().also { require(it.size == cols) } }
private fun readLongArray2d(rows: Int, cols: Int) = Array(rows) { readLongArray().also { require(it.size == cols) } }
private fun readIntArray2d(rows: Int, cols: Int) = Array(rows) { readIntArray().also { require(it.size == cols) } }
private fun readFloatArray2d(rows: Int, cols: Int) = Array(rows) { readFloatArray().also { require(it.size == cols) } }
private fun readDoubleArray2d(rows: Int, cols: Int) = Array(rows) { readDoubleArray().also { require(it.size == cols) } }

private fun isWhiteSpace(c: Char) = c in " 
	"

// JVM-only targeting code follows next

// readString() via sequence is still slightly faster than Scanner
private fun readString() = generateSequence { System.`in`.read().toChar() }
        .dropWhile { isWhiteSpace(it) }.takeWhile { !isWhiteSpace(it) }.joinToString("")
private fun readByte() = readString().toByte()
private fun readShort() = readString().toShort()
private fun readInt() = readString().toInt()
private fun readLong() = readString().toLong()
private fun readFloat() = readString().toFloat()
private fun readDouble() = readString().toDouble()
private fun readBigInt(radix: Int = 10) = readString().toBigInteger(radix)
private fun readBigDecimal() = readString().toBigDecimal()

private fun readBytes(n: Int) = generateSequence { readByte() }.take(n)
private fun readShorts(n: Int) = generateSequence { readShort() }.take(n)
private fun readInts(n: Int) = generateSequence { readInt() }.take(n)
private fun readLongs(n: Int) = generateSequence { readLong() }.take(n)
private fun readFloats(n: Int) = generateSequence { readFloat() }.take(n)
private fun readDoubles(n: Int) = generateSequence { readDouble() }.take(n)

请注意 Scanner有点慢.这在某些情况下可能很重要,例如竞争性编程,只需替换 扫描仪,带有简单的readLine.即使我的次优 readString() 实现通过序列标记化也是 稍微快一些.与 Kotlin 的内置 readLine() 不同,它允许读取输入标记直到出现任何下一个空格.

Beware that Scanner is somewhat slow. This may be important in some cases like competitive programming where program's execution on large inputs could be made up to two times faster just by replacing Scanner with plain readLine. Even my suboptimal readString() implementation tokenizing via sequence is slightly faster. It allows to read input tokens until any next whitespace unlike Kotlin's built-in readLine().

希望有朝一日一个简洁的、跨平台的、高性能的,将在 Kotlin stdlib 中引入通用的控制台和文件输入解析支持.像readIntreadLong等全局和Reader扩展函数.这不仅对竞争性编程非常有用,而且对于将 Kotlin 作为第一语言学习也是非常有用的.读取数字的概念不应该首先解释集合、lambda 和 monad.

I hope someday a concise, crossplatform, performant, universal for both console and files input parsing support would be introduced in Kotlin stdlib. Like readInt, readLong, etc global and Reader extension functions. This would be very userful not only for competitive programming but also for learning Kotlin as first language. A concept of reading a number shouldn't require first explaining collections, lambdas and monads.

奖金

有时您从控制台输入/输出开始,但随后需要切换到文件.在每次读取或写入调用之前都添加文件流变量变得太乏味了.

Sometimes you start with console input/output but then need to switch to files. It becomes too tedious to prepend every read or write call with file stream variable.

这是 Kotlin 魔法的和平之处,它允许只用几行代码包装未更改的控制台代码,以强制它读写文件并确保它们正确关闭:

Here is a peace of Kotlin magic that allows to just wrap unchanged console code with a couple of lines to force it read and write to files also ensuring they are closed properly:

fun <T : Closeable, R> T.useWith(block: T.() -> R): R = use { with(it, block) }

File("a.in").bufferedReader().useWith {
    File("a.out").printWriter().useWith {
        val (a, b) = readLine()!!.split(' ').map(String::toInt)
        println(a + b)
    }
}

Scanner(File("b.in")).useWith {
    PrintWriter("b.out").useWith {
        val a = nextInt()
        val b = nextInt()
        println(a + b)
    }
}

当需要切换回控制台时,可以快速注释掉换行.

Wrapping lines can be quickly commented out when happens a need to switch back to console.

这篇关于在 Kotlin 中读取控制台输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆