input - 在 Kotlin 中读取控制台输入

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

我从主要开始

fun main(args: Array<String>) {

}

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

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

最佳答案

Note that since Kotlin 1.6 readLine()!! should be replaced with readln().

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

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/

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

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 " \r\n\t"

// 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是 somewhat slow .这在某些情况下可能很重要,例如竞争性编程,只需替换 Scanner 就可以使程序在大输入上的执行速度提高两倍。与平原 readLine .甚至我的次优 readString() 实现通过序列进行标记化是 slightly faster .它允许读取输入标记,直到任何下一个空格,这与 Kotlin 的内置 readLine() 不同。

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


奖金

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

这是 Kotlin 魔法的一种平静,它允许只用几行代码包装未更改的控制台代码,以强制它读取和写入文件,同时确保它们被正确关闭:

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)
    }
}

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

https://stackoverflow.com/questions/41283393/

相关文章:

string - 为什么 Kotlin 中 null + null 的类型是隐式 String?

java - Kotlin 获取类型为字符串

android - 产品 flavor : Duplicate class found

kotlin - 函数定义: fun vs val

android - 类 'MyFirebaseMessagingService' 不是抽象的,也没有

java - 如何在 Java 中访问 Kotlin 伴随对象?

file - 在 Kotlin 中递归列出文件

android - kotlin 中的重载解析歧义错误

kotlin - Kotlin 中的交换函数

android - 如何像在 Swift 中一样从 Kotlin 中的函数返回多个值?