Java字符串数组输入输出时Scanner少读n-1个字符串的原因排查
问题根因
这个异常完全由Scanner类的输入读取逻辑差异导致,和数组初始化、循环次数判断逻辑没有关系:
- 调用
sc.nextInt()读取数字时,方法只会从输入缓冲区中提取连续的数字字符转换为整数,不会消费掉用户输入数字后按下回车生成的换行符(\n),这个换行符会一直残留在输入缓冲区中。 - 后续循环读取字符串时,
sc.nextLine()的读取规则是:读取当前指针位置到下一个换行符之间的全部内容,读取完成后会把对应的换行符移出缓冲区。由于缓冲区中已经存在nextInt()遗留的换行符,第一次调用nextLine()时根本不会阻塞等待用户输入,直接把这个残留换行符作为分隔符,读取到一个长度为0的空字符串,直接存入数组的第一个位置。 - 按输入数量3次循环计算:第1次循环读走残留的空行,第2、3次循环才会真正阻塞等待用户输入。最终数组内的存储内容为[空字符串, 用户输入的第1个字符串, 用户输入的第2个字符串],执行输出时先打印一个空行,再打印用户输入的两个内容,给人的直观感受就是程序只接收了2个输入就提前执行了输出逻辑。
常用修复方案
- 方案1:在
sc.nextInt()读取完输入数量后,手动补一行sc.nextLine()消费掉缓冲区残留的换行符,让后续的nextLine()可以正常等待用户输入整行字符串。核心修改代码如下:
int n=sc.nextInt(); sc.nextLine(); // 清理nextInt遗留的换行符 String[] str = new String[n];
这种方案适配所有需要读取带空格整行字符串的场景,通用性更强。
- 方案2:如果需要读取的字符串本身不包含空格,可以把循环内的
sc.nextLine()替换为sc.next()。next()方法会自动跳过前置的所有空白字符(包括换行、空格、制表符),直接读取第一个非空白字符到下一个空白字符之间的内容,也可以避开残留换行的问题。但该方案无法读取包含空格的整行输入,有场景限制。
内容的提问来源于stack exchange,提问作者Navjyo
相关产品推荐
相关产品推荐

