为何compareTo方法的输入验证会导致输出结果异常?
输入数字触发验证后,姓名比较逻辑错误显示“两个姓名相同”
我需要实现一个方法比较用户输入的两个姓名,按字母顺序输出排序结果。正常输入时功能正常,但故意输入数字触发输入验证后,输出总是错误显示“两个姓名相同”(即使姓名不相等);测试一个输入正确、一个触发验证的情况时,还会出现输出“ is first alphabetically”(姓名为空)的问题。
原代码
import java.util.Scanner; public class NameSorter { public static void alpha() { //takes two names, makes them lowercase, and sorts them using uniCode System.out.println("Please input the first name you want me to organize."); String firstC = isValidString(); String fir = firstC.toLowerCase(); System.out.println("Please input the second name you want me to organize."); String secondC = isValidString(); String sec = secondC.toLowerCase(); int uniOut = fir.compareTo(sec); if (uniOut > 0) { System.out.printf("%s is first alphabetically", secondC); } else if (uniOut < 0) { System.out.printf("%s is first alphabetically", firstC); } else { System.out.println("Those names are the same."); } } public static String isValidString() { //validates input as a string and has the user continue to input until it is a string Scanner in = new Scanner(System.in); while (in.hasNextDouble()) { double input = in.nextDouble(); System.out.printf("%f is not a valid input, please try again.\n", input); } String s = in.nextLine(); return s; } }
问题根源
- Scanner重复创建:每次调用
isValidString()都新建Scanner实例,会导致输入流读取混乱。 - 换行符残留:当用
in.nextDouble()读取数字后,输入流中数字后的换行符未被消费,后续in.nextLine()会直接读取这个空换行符,返回空字符串。两个空字符串的compareTo()结果为0,因此错误显示“姓名相同”;若一个为空、一个为有效姓名,就会出现空姓名的输出。
修复方案
修改验证逻辑,共用一个Scanner实例,直接读取整行输入并判断是否为数字,避免换行符残留问题:
import java.util.Scanner; public class NameSorter { public static void alpha() { Scanner in = new Scanner(System.in); System.out.println("Please input the first name you want me to organize."); String firstC = isValidString(in); String fir = firstC.toLowerCase(); System.out.println("Please input the second name you want me to organize."); String secondC = isValidString(in); String sec = secondC.toLowerCase(); int uniOut = fir.compareTo(sec); if (uniOut > 0) { System.out.printf("%s is first alphabetically%n", secondC); } else if (uniOut < 0) { System.out.printf("%s is first alphabetically%n", firstC); } else { System.out.println("Those names are the same."); } in.close(); } public static String isValidString(Scanner in) { while (true) { String input = in.nextLine().trim(); // 正则匹配整数/小数格式的数字 if (input.matches("-?\\d+(\\.\\d+)?")) { System.out.printf("%s is not a valid input, please try again.%n", input); } else if (input.isEmpty()) { System.out.println("Empty input is not allowed, please try again."); } else { return input; } } } public static void main(String[] args) { alpha(); } }
修改说明
- 共用Scanner:在
alpha()中创建一个Scanner实例并传入验证方法,避免输入流混乱。 - 整行读取+正则判断:用
in.nextLine()读取完整输入行,通过正则判断是否为数字,不会残留换行符。 - 空输入处理:增加空输入的验证,避免用户直接回车的无效输入。
- 去除首尾空格:用
trim()处理输入,避免用户输入前后空格导致的判断错误。
内容的提问来源于stack exchange,提问作者Topy
相关产品推荐
相关产品推荐

