Java扫描程序在循环时数据类型验证中输入错误后未读取换行符

Java扫描程序在循环时数据类型验证中输入错误后未读取换行符,java,while-loop,java.util.scanner,Java,While Loop,Java.util.scanner,我已经研究过类似的问题,并尝试按照解决其他人问题的答案进行操作,但将sc.next()或sc.nextLine()放在while循环之后会导致它进入无限循环 问题是,如果用户在输入正确信息之前多次输入错误的输入(无或数字),我会得到空行。如我的输出块中所示,当我为名字输入1时,我必须输入两次才能输出错误的格式,然后输入空行,直到我输入另一种类型的字符,它才会读取 我知道这与nextInt()不读取换行符有关,但如何让它在这种方法中正常工作 protected static void setFir

我已经研究过类似的问题,并尝试按照解决其他人问题的答案进行操作,但将sc.next()或sc.nextLine()放在while循环之后会导致它进入无限循环

问题是,如果用户在输入正确信息之前多次输入错误的输入(无或数字),我会得到空行。如我的输出块中所示,当我为名字输入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);        
}
以下是当我首先输入一个数字,然后返回空白时得到的输出:

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:
以下是我在输入空白报税表和数字时得到的输出:

First Name: 
Name is empty. Please Try again.
First name:
1
1
1
1
Incorrect Name format. Please Try again.
First name: 
试试这个方法

我不知道你在哪里打开和关闭了
扫描仪,所以我也把它忘了。只需确保
close()
it

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);

}
试试这个方法

我不知道你在哪里打开和关闭了
扫描仪,所以我也把它忘了。只需确保
close()
it

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);

}
试试这个方法

我不知道你在哪里打开和关闭了
扫描仪,所以我也把它忘了。只需确保
close()
it

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);

}
试试这个方法

我不知道你在哪里打开和关闭了
扫描仪,所以我也把它忘了。只需确保
close()
it

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问题(和答案)


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

您从扫描仪上读取的内容太多了

在这一行

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问题(和答案)


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

您从扫描仪上读取的内容太多了

在这一行

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问题(和答案)


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

您从扫描仪上读取的内容太多了

在这一行

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问题(和答案)

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

这样做:

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();
}
如果该行未填写,则不计算在内。

如下所示:

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();
}
如果该行未填写,则不计算在内。

如下所示:

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();
}
如果该行未填写,则不计算在内。

如下所示:

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();
}

如果这行没有填写,那就不算了。

你的问题不太清楚到底出了什么问题。但是混合调用
sc.next()
(通常不会从获取输入的行尾提取换行符)和
sc.nextLine()
,这是一个非常糟糕的主意。尝试将三个呼叫更改为
sc.next()
sc.nextLine()
。谢谢,我已经按照你的建议做了。你的问题并不清楚到底出了什么问题。但是混合调用
sc.next()
(通常不会从获取输入的行尾提取换行符)和
sc.nextLine()
,这是一个非常糟糕的主意。尝试将三个呼叫更改为
sc.next()
sc.nextLine()
。谢谢,我已经按照你的建议做了。你的问题并不清楚到底出了什么问题。但是混合调用
sc.next()
(通常不会从获取输入的行尾提取换行符)和
sc.nextLine()
,这是一个非常糟糕的主意。试着把你的三个电话改成
sc.next()
sc.nextLine()
。谢谢,我已经按照你的建议做了。你的问题不是很好