Java循环输入成绩时出现空行卡顿的问题求助
大家好,我最近写了一个处理学生信息的Java程序,遇到了一个奇怪的输入问题:程序在第一次循环输入的时候一切正常,但从第二次循环开始,输入学生姓名时会先出现一个空行,我输入内容后,后面的循环也一直保持这个状态,每次都要多处理一个空行,搞得我很头疼。
我试过在不同的输入语句后面添加或者移除in.nextLine(),甚至还尝试过创建第二个Scanner对象,但都没能解决这个问题。
下面是我的代码:
import java.util.Scanner; public class parallel_arrays { public static void main(String args[]) { Scanner in = new Scanner(System.in); System.out.print("\nHow many Students? "); int number = in.nextInt(); String names[] = new String[number]; int grades[] = new int[number]; int studID[] = new int [number]; String homeroom[] = new String[number]; for (int index = 0; index < grades.length; index++) { System.out.print("\nStudent Name: "); names[index] = in.nextLine(); in.nextLine(); System.out.print("Grade: "); grades[index] = in.nextInt(); in.nextLine(); System.out.print("Student ID: "); studID[index] = in.nextInt(); in.nextLine(); System.out.print("Homeroom Number: "); homeroom[index] = in.nextLine(); } System.out.println("\nStudent Data"); System.out.println("=============="); for (int index = 0; index < grades.length; index++) { System.out.println("Student: " + names[index]); System.out.println("Grade: " + grades[index]); System.out.println("Grade: " + studID[index]); System.out.println("Grade: " + homeroom[index]); System.out.println("-------------------------"); } } }
问题原因分析
其实这个问题的根源在于Scanner的输入缓冲区残留的换行符:
当你使用in.nextInt()这类方法读取整数时,它只会读取数字部分,不会消耗掉你输入数字后按下的回车(也就是换行符\n)。这个残留的换行符会留在输入缓冲区里,等到下一次调用in.nextLine()时,它会直接读取这个换行符,导致看起来像是程序“跳过”了你的输入,出现空行的情况。
再看你的代码,还有一个额外的问题:在读取学生姓名时,你连续调用了两次in.nextLine()——第一次读取的是之前nextInt()残留的换行符(导致names[index]被赋值为空字符串),第二次才是真正读取你输入的姓名,但你没有把这个值存到数组里,这就导致姓名信息丢失,同时后续的输入操作继续被残留的换行符干扰。
解决方案
方案一:修复现有代码的nextLine()调用
我们只需要清理掉残留的换行符,并且移除多余的in.nextLine()调用即可:
import java.util.Scanner; public class parallel_arrays { public static void main(String args[]) { Scanner in = new Scanner(System.in); System.out.print("\nHow many Students? "); int number = in.nextInt(); // 清理读取学生数量后残留的换行符 in.nextLine(); String names[] = new String[number]; int grades[] = new int[number]; int studID[] = new int [number]; String homeroom[] = new String[number]; for (int index = 0; index < grades.length; index++) { System.out.print("\nStudent Name: "); // 直接读取姓名,此时缓冲区已经没有残留换行 names[index] = in.nextLine(); System.out.print("Grade: "); grades[index] = in.nextInt(); // 清理读取成绩后残留的换行符 in.nextLine(); System.out.print("Student ID: "); studID[index] = in.nextInt(); // 清理读取ID后残留的换行符 in.nextLine(); System.out.print("Homeroom Number: "); homeroom[index] = in.nextLine(); } System.out.println("\nStudent Data"); System.out.println("=============="); for (int index = 0; index < grades.length; index++) { System.out.println("Student: " + names[index]); System.out.println("Grade: " + grades[index]); System.out.println("Student ID: " + studID[index]); // 修正原代码的标签错误 System.out.println("Homeroom: " + homeroom[index]); System.out.println("-------------------------"); } } }
方案二:统一使用nextLine()读取所有输入(更推荐)
为了彻底避免这类缓冲区问题,我们可以统一用in.nextLine()读取所有输入内容,然后将需要转换为整数的部分用Integer.parseInt()方法转换,这样就不会残留任何换行符了:
import java.util.Scanner; public class parallel_arrays { public static void main(String args[]) { Scanner in = new Scanner(System.in); System.out.print("\nHow many Students? "); // 读取整行后转为整数 int number = Integer.parseInt(in.nextLine()); String names[] = new String[number]; int grades[] = new int[number]; int studID[] = new int [number]; String homeroom[] = new String[number]; for (int index = 0; index < grades.length; index++) { System.out.print("\nStudent Name: "); names[index] = in.nextLine(); System.out.print("Grade: "); grades[index] = Integer.parseInt(in.nextLine()); System.out.print("Student ID: "); studID[index] = Integer.parseInt(in.nextLine()); System.out.print("Homeroom Number: "); homeroom[index] = in.nextLine(); } System.out.println("\nStudent Data"); System.out.println("=============="); for (int index = 0; index < grades.length; index++) { System.out.println("Student: " + names[index]); System.out.println("Grade: " + grades[index]); System.out.println("Student ID: " + studID[index]); System.out.println("Homeroom: " + homeroom[index]); System.out.println("-------------------------"); } } }
另外,我还顺便修正了你输出部分的一个小错误——原来的代码把Student ID和Homeroom的输出标签都写成了Grade,现在已经改过来了。
备注:内容来源于stack exchange,提问作者Matthew Basile

