尝试使用 do while 循环进行 catch

try catch with a do while loop

提问人:Jerry Prosper 提问时间:5/26/2021 最后编辑:Jerry Prosper 更新时间:5/27/2021 访问量:78

问:

使用我的代码,我试图告诉用户在用户整数之前不要输入字符串,但在运行程序时它是无限的。

public static void main(String[] args) {

  int age = 1;
  Utilisateur utilisateur = new Utilisateur();
  Scanner u = new Scanner(System.in);

  System.out.println("Enter your Name: ");
  utilisateur.setNom(u.nextLine());
  System.out.println("Enter your Surname: ");
  utilisateur.setPrenom(u.nextLine());
  System.out.println("Enter your Matricule: ");
  utilisateur.setMatricule(u.nextLine());
  System.out.println("Enter your Sexe: ");
  utilisateur.setSexe(u.nextLine());

  do {
    try {
      System.out.println("Enter your Age: ");
      utilisateur.setAge(u.nextInt());
      System.out.println(utilisateur.detail());
      age = 2;
    } catch (Exception e) {
      System.out.println("Enter a valid age ");

    }
  }
  while (age == 1);
}
}
java try-catch java.util.scanner do-while

评论

1赞 evolutionxbox 5/26/2021
我已经删除了 JavaScript 标签,因为这是 Java。
0赞 5/26/2021
我删除了连接到您的类的任何内容,并且可以毫无问题地运行代码,也没有任何无限循环。因此,我强烈怀疑您在块中调用的方法之一会引发异常并导致问题。尝试在 catch 块中打印堆栈跟踪,并查看是否或导致抛出异常(例如 NullPointerException)Utilisateurutilisateurtryutilisateur.setAgeutilisateur.detail()

答:

0赞 Hooman 5/26/2021 #1

您应该添加 catch 块,以跳过在扫描仪中输入的无效值。u.nextLine();

0赞 Haakon Løtveit 5/26/2021 #2

好的,让我们从清理代码开始。整个“年龄”变量有点奇怪。它似乎包含一些关于你是否读过年龄的状态。但这有点布尔值,不是吗?因此,让我们重做代码时要牢记这一点。我会先将 do-while 更改为简单的 while,但我们可以稍后将其改回。此外,如果您更喜欢法语,最好将“u”重命名为“keyboard”或“clavier”。

    public static void main(String[] args) {
        Utilisateur utilisateur = new Utilisateur();
        Scanner clavier = new Scanner(System.in);

        System.out.println("Enter your Name: ");
        utilisateur.setNom(clavier.nextLine());
        System.out.println("Enter your Surname: ");
        utilisateur.setPrenom(clavier.nextLine());
        System.out.println("Enter your Matricule: ");
        utilisateur.setMatricule(clavier.nextLine());
        System.out.println("Enter your Sexe: ");
        utilisateur.setSexe(clavier.nextLine());

        boolean hasEnteredAge = false;
        while(!hasEnteredAge) {
                System.out.println("Enter your Age: ");
                String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
            try {
                int age = Integer.parseInt(ageInput);
                utilisateur.setAge(age);
                System.out.println(utilisateur);
                hasEnteredAge = true;
            } catch (Exception e) {
                System.out.println("Enter a valid age.");
            }
        }
    }
}

请注意,我将变量移到了循环的开头,这是我们需要了解这一事实的地方,以及我们如何将其初始化为 false。我们现在必须在之后将其设置为 true。

但我认为这里还有更多事情要做。我们有一堆打印件,然后是输入。当然,这可以被培养成一种方法,让它看起来更好一些?但在我们这样做之前,我们应该再看一下循环。我们可以通过多种方式进行循环。我们能做到

        do {
            System.out.println("Enter your Age: ");
            String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
            try {
                int age = Integer.parseInt(ageInput);
                utilisateur.setAge(age);
                System.out.println(utilisateur);
                break; // this means that we should exit the loop
            } catch (Exception e) {
                System.out.println("Enter a valid age.");
            }
        }while(true); // So if we ever get here, we're not done.

在这里,我们依靠休息来摆脱困境。这有效,但我个人不喜欢它。然而,这并不是一件错误的事情,所以我就把它留在里面。您也可以像旧的 do-while 循环一样使用它:

boolean hasEnteredAge = false;
        do {
                System.out.println("Enter your Age: ");
                String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
            try {
                int age = Integer.parseInt(ageInput);
                utilisateur.setAge(age);
                System.out.println(utilisateur);
                hasEnteredAge = true;
            } catch (Exception e) {
                System.out.println("Enter a valid age.");
            }
        } while (!hasEnteredAge);

不过,无论您选择哪种方式,都可以。 现在让我来谈谈印刷线的问题,并阅读:

如果你添加一个方法“prompt”来接受一个提示并返回一个字符串,你可以非常方便地简化它,如下所示:

public class EnterNameHere {
    private static Scanner clavier = new Scanner(System.in);

    public static String prompt(String prompt) {
        System.out.println(prompt);
        return clavier.nextLine().trim();
    }
    // ... The rest is as before.
}

现在,部分阅读变得非常简单:

    public static void main(String[] args) {
        Utilisateur utilisateur = new Utilisateur();

        utilisateur.setNom(prompt("Enter your Name: "));
        utilisateur.setPrenom(prompt("Enter your surname: "));
        utilisateur.setMatricule(prompt("Enter your matricule: "));
        utilisateur.setSexe(prompt("Enter your sex: "));

一个重要的问题出现了:如果我们要对字符串输入这样做,为什么不对整数 (int) 输入也这样做呢? 我建议:

public static int promptInt(String prompt) {
        String value = prompt(prompt);
        try {
            return Integer.parseInt(value);
        } catch(NumberFormatException ignored) {
            System.out.println("Invalid number: '" + value + "'");
            return promptInt(prompt); // We try again!
        }
    }

请注意,如果您非常友善,如果调用方法 promptInt 不起作用,我们会打印一条错误消息,然后重试。在全部崩溃之前,这只能工作几百次,但这应该足够了。(当然,如果您不希望这种情况发生,您可以采用之前的 while-loop 方法。这种方法或函数多次调用自身直到工作完成,这种技巧称为“递归”,它与循环一样强大。对于刚接触编程的人来说,这可能会让人感到困惑,但我认为这个例子很简单。如果不是,您可以简单地替换整个循环,如上所述。当然,有一种方法叫做 prompt,另一种叫做 promptInt。为了避免任何混淆,我们将 prompt-method 重命名为 promptString,整个程序就变成了:

public class YourNameHere {
    private static final Scanner clavier = new Scanner(System.in);

    public static String promptString(String prompt) {
        System.out.print(prompt);
        return clavier.nextLine().trim();
    }

    public static int promptInt(String prompt) {
        String value = promptString(prompt);
        try {
            return Integer.parseInt(value);
        } catch(NumberFormatException ignored) {
            System.out.println("Invalid number: '" + value + "'");
            return promptInt(prompt); // We try again!
        }
    }

    public static void main(String[] args) {
        Utilisateur utilisateur = new Utilisateur();

        utilisateur.setNom(promptString("Enter your Name: "));
        utilisateur.setPrenom(promptString("Enter your surname: "));
        utilisateur.setMatricule(promptString("Enter your matricule: "));
        utilisateur.setSexe(promptString("Enter your sex: "));
        utilisateur.setAge(promptInt("Enter your age: "));

        System.out.println("You have created an utilisateur: " + utilisateur);
    }
}

当然还有 Utilisateur 的定义。 我认为这是一种更简单的方法,通过创建为您完成无聊工作的方法,您可以阅读 main 方法中的代码并立即了解正在发生的事情。如果你需要了解如何操作,你可以上去看看帮助提示方法。