Kotlin中NumberFormatException问题:CodeChef输入处理报错排查
问题描述
在CodeChef上解决VDATES题目时,使用以下Kotlin代码处理输入并转换为整数:
fun main(){ var t = readLine()!!.toInt() for(i in 0 until t){ val (d,l,r) = readLine()!!.split(" ").map{ it -> it.toInt()} if(d<l){ println("Too Early") } else if(d>r){ println("Too Late") } else{ println("Take second dose now") } } }
运行时触发NumberFormatException,错误信息如下:
Exception in thread "main" java.lang.NumberFormatException: For input string: "" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:678) at java.base/java.lang.Integer.parseInt(Integer.java:786) at ProgKt.main(prog.kt:4) at ProgKt.main(prog.kt)
问题根源是空字符串无法转换为整数,需要排查并解决输入处理问题。
解决方案
问题原因
报错是因为readLine()!!读到了空字符串(可能是输入中的空行、多余换行符,或是输入结束后仍尝试读取),调用toInt()时自然抛出异常;另外直接用split(" ")处理含连续空格的输入时,会生成空字符串元素,同样会触发错误。
修复代码
可以通过两种方式优化输入处理:
方式1:过滤空字符串并处理连续空格
修改输入读取和转换逻辑,先过滤无效空内容,再进行数字转换:
fun main() { val t = readLine()?.trim()?.toInt() ?: 0 repeat(t) { val input = readLine()?.trim() ?: "" val parts = input.split(Regex("\\s+")).filter { it.isNotEmpty() }.map { it.toInt() } if (parts.size == 3) { val (d, l, r) = parts when { d < l -> println("Too Early") d > r -> println("Too Late") else -> println("Take second dose now") } } } }
方式2:一次性读取所有输入(更稳健)
一次性读取所有有效输入行,再按顺序处理,避免单个readLine()的空值问题:
fun main() { val input = generateSequence(::readLine) .map { it.trim() } .filter { it.isNotEmpty() } .toList() var index = 0 val t = input[index++].toInt() repeat(t) { val parts = input[index++].split(Regex("\\s+")).map { it.toInt() } val (d, l, r) = parts when { d < l -> println("Too Early") d > r -> println("Too Late") else -> println("Take second dose now") } } }
关键优化点
- 使用
trim()去掉每行首尾空白,避免空行被误读 - 用
Regex("\\s+")代替" "分割输入,处理多个连续空格的情况 - 过滤空字符串,确保转换的都是有效数字内容
- 避免使用
!!强制非空,改用安全调用?.和默认值,增强代码健壮性
内容的提问来源于stack exchange,提问作者JavaBoi
相关产品推荐
相关产品推荐

