为何Scanner.next().charAt(0)在输入含空格时会读取多个字符?
问题:Scanner读取输入首字符时,带空格的输入导致变量被覆盖
我希望代码仅读取用户输入的第一个字符,但输入包含空格时程序异常:无空格输入能正常存储首字符;输入两个单词时,程序先存第一个单词的首字符,执行后续代码后,又会用第二个单词的首字符覆盖变量,多单词输入情况类似。我原以为空格是一个字符,不理解为何会重新开始字符计数。
原代码:
import java.util.Scanner; public class test1 { static Scanner scn = new Scanner(System.in); static char yn; public static void main(String[] args) { System.out.println("Would you like to change anything? (Y/N)"); yn = scn.next().charAt(0); yn = Character.toUpperCase(yn); answer(); } static void answer(){ // Loop until their answer is one of the options while (yn != 'Y' && yn != 'N') { System.out.println("Please input Y for yes or N for no"); System.out.println("Would you like to change anything? (Y/N)"); yn = scn.next().charAt(0); yn = Character.toUpperCase(yn); } } }
尝试的无效代码:
import java.util.Scanner; public class test1 { static Scanner scn = new Scanner(System.in); static char yn; static String yesno; public static void main(String[] args) { System.out.println("Would you like to change anything? (Y/N)"); yesno = scn.next(); yn = yesno.charAt(0); yn = Character.toUpperCase(yn); answer(); } static void answer(){ // Loop until their answer is one of the options while (yn != 'Y' && yn != 'N') { System.out.println("Please input Y for yes or N for no"); System.out.println("Would you like to change anything? (Y/N)"); yesno = scn.next(); yn = yesno.charAt(0); yn = Character.toUpperCase(yn); } } }
问题原因
问题出在Scanner.next()方法的特性上——它默认以空白字符(空格、换行、制表符等)作为分隔符,每次只读取一个连续的非空白字符序列(也就是"单词")。当你输入带空格的内容(比如abc def)时:
- 第一次调用
next()会读取abc,取首字符a赋值给yn; - 后续循环里再次调用
next()时,Scanner会直接读取缓冲区中剩下的def,取首字符d覆盖yn,而不是等待用户输入新内容。
这就是多单词输入会导致变量被多次覆盖的核心原因。
解决方案
要读取整行输入的第一个字符,不管输入中有没有空格,应该使用Scanner.nextLine()方法(读取完整的一行输入,直到换行符),再从中提取首字符。同时要处理输入为空的情况,避免数组越界异常。
修改后的代码:
import java.util.Scanner; public class Test1 { static Scanner scn = new Scanner(System.in); static char yn; public static void main(String[] args) { System.out.println("Would you like to change anything? (Y/N)"); // 读取整行输入并去除首尾空白 String input = scn.nextLine().trim(); // 处理空输入,避免调用charAt(0)抛出异常 yn = input.isEmpty() ? ' ' : input.charAt(0); yn = Character.toUpperCase(yn); answer(); } static void answer() { while (yn != 'Y' && yn != 'N') { System.out.println("Please input Y for yes or N for no"); System.out.println("Would you like to change anything? (Y/N)"); String input = scn.nextLine().trim(); yn = input.isEmpty() ? ' ' : input.charAt(0); yn = Character.toUpperCase(yn); } } }
修改说明
- 用
nextLine()替代next():读取完整的一行输入,包含空格在内的所有字符; - 调用
trim():去除输入首尾的空白字符,避免用户输入空格、换行导致的空字符串问题; - 增加空输入判断:防止输入为空时调用
charAt(0)抛出StringIndexOutOfBoundsException。
内容的提问来源于stack exchange,提问作者Ziadyo
相关产品推荐
相关产品推荐

