在循环

时间:2015-06-22 06:41:35

标签: java while-loop java.util.scanner

我已经查看了类似的问题,并尝试按照解决其他人所遇到的问题的答案,但在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);        
}

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

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: 

3 个答案:

答案 0 :(得分:4)

你从扫描仪上读得太多了!

在这一行

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

答案 1 :(得分:0)

尝试这种方法

我不知道你打开了哪里并关闭了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);

}

答案 2 :(得分:-1)

像这样:

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

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