Java中Scanner与循环结合出现NoSuchElementException问题求助
解决Java Scanner循环菜单中的NoSuchElementException问题
嘿,我太懂你现在的困扰了——这种Scanner的NoSuchElementException在循环菜单里简直是个顽固的小坑,哪怕你加了额外的nextLine()或nextInt(),它还是会找上门来。其实核心问题大多出在输入缓冲区里残留的换行符,咱们一步步来解决它。
问题根源
当你用in.nextInt()选择菜单选项时,它只会读取控制台输入的数字,而数字后面的换行符(就是你按回车的那个字符)会留在输入缓冲区里。接下来如果你的case 1里用了in.nextLine()去读取进程名称这类文本,它会直接把缓冲区里的空换行符当成输入,导致你预期的用户输入被跳过;更糟的情况是,如果后续再调用nextInt(),缓冲区已经空了,就会直接抛出NoSuchElementException。
具体解决方案
这里给你两种靠谱的处理方式,选哪种都能解决问题:
1. 每次用nextInt()后清空换行符
在你读取菜单选项的nextInt()之后,立刻加一行in.nextLine(),专门吃掉残留的换行符。这样后续的输入读取就能正常工作了。修改后的代码片段大概是这样:
Scanner in = new Scanner(System.in); boolean done = false; while (!done) { System.out.println("Welcome, please type a number for selecting from the following: \n 1. Insert Process \n 2. Print out a list of processes \n 3. See and remove first priority process \n 4. Exit"); int choice = in.nextInt(); in.nextLine(); // 关键:清空nextInt()留下的换行符 switch(choice) { case 1: System.out.println("Enter process name:"); String processName = in.nextLine(); // 现在能正常读取用户输入的名称了 System.out.println("Enter process priority:"); int priority = in.nextInt(); in.nextLine(); // 如果这里用了nextInt,同样要清空换行符 // 执行插入进程的逻辑 break; case 2: // 打印进程列表逻辑 break; case 3: // 移除最高优先级进程逻辑 break; case 4: done = true; System.out.println("Exiting program..."); break; default: System.out.println("Invalid choice, please try again!"); } } in.close(); // 程序结束后再关闭Scanner,别在循环里关!
2. 统一用nextLine()读取所有输入(更省心)
如果你不想每次都记着清换行符,可以把所有输入都用nextLine()读取,然后手动转换成整数。这种方式能彻底避免缓冲区残留的问题:
Scanner in = new Scanner(System.in); boolean done = false; while (!done) { System.out.println("Welcome, please type a number for selecting from the following: \n 1. Insert Process \n 2. Print out a list of processes \n 3. See and remove first priority process \n 4. Exit"); // 用nextLine读取整行,再转成整数 String input = in.nextLine(); int choice = Integer.parseInt(input); switch(choice) { case 1: System.out.println("Enter process name:"); String processName = in.nextLine(); System.out.println("Enter process priority:"); int priority = Integer.parseInt(in.nextLine()); // 插入进程逻辑 break; // 其他case逻辑... case 4: done = true; break; } } in.close();
额外注意点
- 绝对不要在循环内部调用
in.close()!一旦关闭了Scanner,对应的输入流也会被关闭,后续循环再调用任何nextXXX()方法都会直接抛出异常。 - 如果你的程序是从文件读取输入,那还要检查文件是否已经读完,但从你的描述看是控制台菜单,所以主要关注上面的换行符问题就行。
内容的提问来源于stack exchange,提问作者Ian S.
相关产品推荐
相关产品推荐

