Scanner运算符字符输入机制解析及nextLine报错问题咨询
问题解析:Scanner中next()和nextLine()读取字符的差异
这个问题我之前帮别人排查过好几次,核心就在于Scanner类的不同输入方法对换行符的处理逻辑完全不一样,咱们来一步步弄明白:
为什么用nextLine()会报错?
先看你的代码流程:
- 用
s.nextInt()读取第一个整数时,输入完成后你会按回车——这个回车会生成一个\n(换行符),但nextInt()只会读取整数本身,不会消耗这个换行符,它会留在输入缓冲区里。 - 同理,读取第二个整数后,缓冲区里又多了一个残留的
\n。 - 当你调用
s.nextLine()时,它会直接读取当前位置到下一个换行符之间的所有内容——也就是刚才残留的空换行,得到一个空字符串。这时候调用charAt(0),自然会抛出StringIndexOutOfBoundsException,因为空字符串没有索引为0的字符。
而s.next()为什么能正常工作?因为next()的行为是:
- 自动跳过所有前置的空白字符(包括换行、空格、制表符)
- 然后读取直到遇到下一个空白字符为止的内容
所以它会跳过之前残留的换行符,直接读取你输入的运算符(比如+、-),这时候调用charAt(0)就能拿到正确的字符。
解决办法:两种方案任选
方案1:手动清理残留的换行符
在每次nextInt()之后,调用一次空的nextLine()来吃掉缓冲区里的换行符,这样后续的nextLine()就能正常读取用户输入的运算符了:
import java.util.Scanner; public class Calculator { public static void main(String[] args) { Scanner s = new Scanner(System.in); System.out.println("Enter First Number:"); int a = s.nextInt(); s.nextLine(); // 吃掉第一个整数后的换行符 System.out.println("Enter Second Number:"); int b = s.nextInt(); s.nextLine(); // 吃掉第二个整数后的换行符 System.out.println("Which Operation you want to execute?"); char operation = s.nextLine().charAt(0); // 现在可以正常读取 int result = 0; switch (operation) { case '+' : result = a + b; break; case '-' : result = a - b; break; case '*' : result = a * b; break; case '/' : result = a / b; break; case '%' : result = a % b; break; default: System.out.println("Invalid Operator!"); } System.out.println(result); s.close(); } }
方案2:继续使用next(),但增加输入校验
如果你觉得手动清理换行符麻烦,继续用next()也可以,但可以加个小校验,避免用户输入多字符导致的错误:
// 读取运算符部分修改为: System.out.println("Which Operation you want to execute?"); String opStr = s.next(); if (opStr.length() != 1) { System.out.println("Invalid Operator! Please enter a single character (+, -, *, /, %)"); s.close(); return; } char operation = opStr.charAt(0);
这样如果用户不小心输入了类似plus这样的字符串,程序会直接提示错误,而不会进入错误的分支。
内容的提问来源于stack exchange,提问作者Dhruv
相关产品推荐
相关产品推荐

