Java while循环在输入有效时仍然给出错误信息

Java do while loop still gives error message when input valid

当给 "Specify Max Time" 的 do while 循环提供有效输入时,它仍然会在中断循环之前给出错误消息。

Scanner console = new Scanner(System.in);
System.out.println("Specify city : ");   
String city;

//loops if input is anything but New York or Paris
do { 
    city = console.next();
    if (!city.equals("New York") && !city.equals("Paris")) {
        System.out.println("Enter valid city");
    }
} while (!city.equals("New York") && !city.equals("Paris"));    
    System.out.println("Specify Max Time (HH:MM) : ");  
    String time;    

//loops if input not is in 24 hour format 
do { 
    time = console.next();  
    if (!time.matches("[0-9]{2}:[0-9]{2}")); {  
        System.out.println("Enter Valid Time (HH:MM) :");
    }                        
} while (!time.matches("[0-9]{2}:[0-9]{2}"));

你的时间正则表达式不好。一个问题是 "[0-9]" 应该是 "[0-9]{2}",另一个是您的代码太复杂了 - 使用一个正则表达式测试整个表达式:

if (!time.matches("\d\d:\d\d"))

你还有一个bug:

在第一个 while 子句中,您测试的是 "paris" 而不是 "Paris"

你可以大大简化模式匹配:

do {
    // Your stuff goes here
} while(!time.matches("[0-9]{2}:[0-9]{2}"));
// --------------------^^^^^^^^^^^^^^^^^
// Easier, don't you think?

此外,您还需要检查小时和分钟的值是否有效:小时的值应介于 0 和 23 之间,分钟的值应介于 0 和 59 之间。


您已经有足够的时间来检查和验证您的代码。我在这里提出我自己的、经过测试的解决方案来解决你的问题因为我感觉很慷慨而且我现在没有更好的事情要做:

import java.util.Scanner;

public class SO_Example_20151205_01 {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        String pattern = "[0-9]{2}:[0-9]{2}";   // The pattern you'll use to validate if the time is valid
        String time;                            // The input variable
        boolean valid_time = false;             // A flag to break the loop. Initialized to false
        int hour, minute;

        // I prefer to use a 'while' loop in this case.
        // The loop will break if the valid_time variable is true
        while(!valid_time) {
            System.out.print("Enter time (HH:MM):\t");
            time = console.next();
            // Check if the input matches the pattern:
            if(time.matches(pattern)) {
                // Now, check if the input values are valid
                hour = Integer.parseInt(time.substring(0,2));
                minute = Integer.parseInt(time.substring(3,5));
                if(hour >= 0 && hour <= 24 && minute >= 0 && minute < 60) {
                    valid_time = true;
                } else {
                    System.out.println("\nYou've entered a valid pattern, but the values are invalid!\n Please try again");
                }
            } else {
                System.out.println("\nYou entered a non recognized pattern. Please try again\n");
            }
        }
        System.out.println("Done!");
    }
}

请注意,使用 while 循环可以避免多次写入。另外,检查我正在使用的模式...它有效!

我经常使用布尔标志来打破我的循环(也许它不是更干净的解决方案,但它有效并且它允许您准确地看到循环即将打破的位置和时间)。此外,我在您的输入中添加了小时和分钟的验证。

这个解决方案故意冗长......这正是我想要的:这样,你会更容易看到发生了什么。

你的程序有很多错误... 1) 将 destination_input 更改为城市,因为您将城市作为输入。

if (!city.equals("New York") && !city.equals("Paris")) {

2) 在 do while 循环中将其更改为 Paris

} while (!city.equals("New York") && !city.equals("Paris"));

3) 将 time_input 更改为时间,因为您将时间作为输入而不是 time_input(变量未在任何地方声明)

4) 更改您的正则表达式以检查时间,因为您的正则表达式只检查一位数,但它会是两位数

time.substring(0, 2).matches("[0-9]{2}")
time.substring(3, 5).matches("[0-9]{2}")

更好的解决方案是使用单个正则表达式

if (!time.matches("\d\d:\d\d"))

5) 将 time.substring(4).matches 替换为 time.charAt(2)==':' .time.substring(4) 将 return 之后的所有字符开始索引 4.

也对您的 while 退出条件进行类似的更改