while循环内Scanner语句导致程序运行时错误:单轮处理后阻塞等待输入
根因说明
程序完成一轮处理后持续阻塞不退出的核心触发点是外层循环的判定逻辑:
while (scanner.hasNext())的判定特性为:只要关联的输入流(这里是标准输入System.in)没有收到明确的EOF结束信号,方法就会进入阻塞状态等待新输入,永远不会主动返回false终止循环- 日常命令行交互场景下,用户输完所有待处理内容按回车,控制台不会自动发送EOF信号;处理完第一行内容后,程序跳回外层循环判定,调用
scanner.hasNext()时因为没有新输入可读,直接进入永久阻塞,根本不会走到后续的输出代码块,和你观察到的异常表现完全匹配。
分场景可落地修复方案
场景1:单批输入处理(匹配示例“单次输入字符串+若干索引”的需求)
直接移除外层无终止条件的循环,读取一次输入行处理完就走输出流程,同时补充必要的边界校验避免运行时报错:
import java.util.*; public class CreateString { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); StringBuilder solution = new StringBuilder(); Scanner inner_scanner = new Scanner(scanner.nextLine()); String str = inner_scanner.next(); while(inner_scanner.hasNextInt()) { int index = inner_scanner.nextInt(); // 新增索引合法性校验,避免越界异常 if(index >= 0 && index < str.length()) { solution.append(str.charAt(index)); } } inner_scanner.close(); System.out.format("%d\n %s",solution.length(),solution); scanner.close(); } }
改完的效果:输完一行内容按回车,程序立刻处理并输出结果,不会进入等待状态。
场景2:需要支持循环处理多批输入
如果确实要逐行处理多组“字符串+索引”的输入,需要给循环增加明确的终止规则,不能依赖scanner.hasNext()的默认阻塞特性:
import java.util.*; public class CreateString { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); StringBuilder solution = new StringBuilder(); // 逐行读取,不再用无终止边界的scanner.hasNext()做判定 while (scanner.hasNextLine()){ String currentLine = scanner.nextLine(); // 规则:读到空行就终止循环,不再等待后续输入 if(currentLine.isBlank()) break; Scanner inner_scanner = new Scanner(currentLine); if(!inner_scanner.hasNext()) { inner_scanner.close(); break; } String str = inner_scanner.next(); while(inner_scanner.hasNextInt()) { int index = inner_scanner.nextInt(); if(index >= 0 && index < str.length()) { solution.append(str.charAt(index)); } } inner_scanner.close(); } System.out.format("%d\n %s",solution.length(),solution); scanner.close(); } }
改完的效果:逐行处理所有输入内容,当用户输入空行按回车,程序立刻终止并输出最终结果,不会永久阻塞。
补充说明:如果是跑在线评测类系统的场景,这种改法也能完美适配——评测系统输完所有测试用例后会自动发送EOF信号,
scanner.hasNextLine()会自动返回false终止循环,不需要额外手动加退出判定。
内容的提问来源于stack exchange,提问作者Ge To
相关产品推荐
相关产品推荐

