Java 在数据类型验证 while 循环中输入错误后,扫描器不读取新行

Java Scanner not reading newLine after wrong input in datatype verification while loop

我看过类似的问题并尝试遵循解决其他人遇到的问题的答案,但是在 while 循环之后放置 sc.next() 或 sc.nextLine() 会导致它进入无限循环。

问题是如果用户在输入正确信息之前多次输入不正确的输入(什么都没有或数字),我会得到空行。如我的输出块所示,当我输入 1 作为名字时,我必须输入它两次才能输出它是错误的格式,然后输入空行之后它不会读取,直到我输入另一个某种字符.

我知道这与 nextInt() 不读取换行符有关,但如何让它在此方法中正常工作?

protected static void setFirstName(){
    System.out.print("First Name: ");

    while(sc.nextLine() == "" || sc.nextLine().isEmpty()){
        System.out.println("Name is empty. Please Try again.\nFirst name:");
        sc.nextLine();
    } 

    while (sc.hasNextInt() || sc.hasNextDouble()) {
        System.out.print("Incorrect Name format. Please Try again.\nFirst name: ");
        sc.nextLine();
        }

    firstName = sc.nextLine();      
    firstName = Character.toUpperCase(firstName.charAt(0)) + firstName.substring(1);        
}

这是我先输入数字然后输入空白时得到的输出 returns:

First Name: 1
1
Incorrect Name format. Please Try again.
First name:



1
Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name:

这是我先输入空白 return 然后输入数字时得到的输出:

First Name: 
Name is empty. Please Try again.
First name:
1
1
1
1
Incorrect Name format. Please Try again.
First name: 

试试这个方法

我不知道你在哪里打开和关闭你的Scanner,所以我也把它漏掉了。只需确保close()它。

public static void setFirstName() {
    System.out.print("First Name: ");

    String firstName = sc.nextLine();
    while (true) {
        try {
            int test = Integer.parseInt(firstName);
        } catch (Exception e) {
            if (firstName != null && !firstName.trim().equals("")) {
                break; // breaks loop, if input is not a number and not empty
            }
        }
        System.out.println("Name is empty. Please Try again.\nFirst name:");
        firstName = sc.nextLine();
    }

    firstName = Character.toUpperCase(firstName.charAt(0))
            + firstName.substring(1);

}

您从扫描仪读取的内容过多!

在这一行

while (sc.nextLine() == "" || sc.nextLine().isEmpty())

您基本上是从扫描仪读取一行,将它 (*) 与 "" 进行比较,然后忘记它,因为您又读取了下一行。因此,如果第一个读取行确实包含名称,则第二个查询 (isEmpty) 将发生在完全不同的字符串上。

结论:读一遍,验证,无效再读

static void setFirstName() {
    String line;
    boolean valid = false;

    do {
        System.out.print("First Name: ");
        line = sc.nextLine();
        if (line.isEmpty()) {
            System.out.println("Name is empty. Please try again.");
        } else if (isNumeric(line)) {
            System.out.print("Incorrect name format. Please try again.");
        } else {
            valid = true;
        }
    } while (!valid);

    firstName = Character.toUpperCase(line.charAt(0)) + line.substring(1);
} 

static boolean isNumeric(String line) {
    ...
}

isNumeric方法有点复杂。查看其他 SO 问题(和答案),例如 this one.

(*) 比较字符串必须使用 equals 方法,而不是 ==。看看here.

像这样:

public static String firstName = null;

public static void setFirstName() {
    firstName = null;
    System.out.println("First Name:");
    Scanner sc = new Scanner(System.in);
    while(firstName == null) {
        String st = sc.next();
        try {
            Double.parseDouble(st);
            System.out.println("Incorrect Name format. Please Try again.");
        } catch(Exception ex) {
            firstName = st;      
            firstName = Character.toUpperCase(firstName.charAt(0)) + firstName.substring(1);
        }
    }
    sc.close();
}

如果该行未填写,则不算数。