如何用Scanner区分输入字符串+整数与仅字符串的场景?
Scanner阻塞问题:输入"q"无法退出程序的解决方案
问题背景
我编写了一段数值加减运算的代码,支持输入add 3为结果加3、subtract 7为结果减7,但输入q时程序会卡住等待输入,无法正常退出。原以为kb.hasNextInt()能检测是否有整数输入,实际未达预期。考虑过用split()拆分整行输入,但希望有更简洁的方案。
原代码如下:
private static int result = 0; public static void main(String[] args){ Scanner kb = new Scanner(System.in); String operation = ""; int num = 0; boolean finished = false; while(!finished){ System.out.println("Enter the operation you'd like to perform on " + result + " or type q to quit."); operation = kb.next(); if(kb.hasNextInt()){ num = kb.nextInt(); } //The problem switch (operation){ case "add": add(num); break; case "subtract": subtract(num); break; case "q": finished = true; break; } System.out.println("New result: " + result); } System.out.println("Bye!"); } public static void add(int num){ result += num; } public static void subtract(int num){ result -= num; }
核心原因
Scanner.hasNextInt()是阻塞式方法:它会忽略输入中的空白字符(比如换行),一直等待用户输入非空白内容,直到能判断该内容是否为整数。当输入q回车后,kb.next()读取了q,但hasNextInt()会继续等待下一个输入,导致程序卡住。
解决方案
方法1:调整逻辑顺序,优先处理退出指令
直接先判断操作是否为q,如果是立即标记退出,跳过后续的整数检测步骤,从根源避免阻塞:
private static int result = 0; public static void main(String[] args){ Scanner kb = new Scanner(System.in); String operation = ""; int num = 0; boolean finished = false; while(!finished){ System.out.println("Enter the operation you'd like to perform on " + result + " or type q to quit."); operation = kb.next(); // 先处理退出,不碰整数检测逻辑 if ("q".equals(operation)) { finished = true; System.out.println("Bye!"); break; } // 非退出指令才检查并读取整数 if(kb.hasNextInt()){ num = kb.nextInt(); } switch (operation){ case "add": add(num); break; case "subtract": subtract(num); break; } System.out.println("New result: " + result); } } public static void add(int num){ result += num; } public static void subtract(int num){ result -= num; }
方法2:整行读取输入(更健壮)
如果担心用户输入格式多变(比如多空格、误输入非数字),用nextLine()整行读取后拆分的方式反而更可靠,且不会出现阻塞问题:
private static int result = 0; public static void main(String[] args){ Scanner kb = new Scanner(System.in); String input = ""; boolean finished = false; while(!finished){ System.out.println("Enter the operation you'd like to perform on " + result + " or type q to quit."); input = kb.nextLine().trim(); String[] parts = input.split("\\s+"); if (parts.length == 0) continue; String operation = parts[0]; int num = 0; switch (operation){ case "add": case "subtract": if (parts.length > 1) { try { num = Integer.parseInt(parts[1]); if ("add".equals(operation)) add(num); else subtract(num); } catch (NumberFormatException e) { System.out.println("无效数字,请重新输入。"); } } else { System.out.println("操作缺少数字,请重新输入。"); } break; case "q": finished = true; break; default: System.out.println("无效操作,请重新输入。"); } if (!finished) System.out.println("New result: " + result); } System.out.println("Bye!"); } public static void add(int num){ result += num; } public static void subtract(int num){ result -= num; }
内容的提问来源于stack exchange,提问作者Babbit
相关产品推荐
相关产品推荐

