essayer/attraper avec InputMismatchException crée boucle infinie

donc je suis en train de construire un programme qui prend des ints à partir des entrées des utilisateurs. J'ai ce qui semble être un très simple bloc try/catch qui, si l'utilisateur n'entre pas un int, doit répéter le bloc jusqu'à ce qu'ils font. Voici la partie du code:

import java.util.InputMismatchException;
import java.util.Scanner;


public class Except {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        boolean bError = true;
        int n1 = 0, n2 = 0, nQuotient = 0;

        do {
            try {
                System.out.println("Enter first num: ");
                n1 = input.nextInt();
                System.out.println("Enter second num: ");
                n2 = input.nextInt();
                nQuotient = n1/n2;
                bError = false;
            } 
            catch (Exception e) {
                System.out.println("Error!");
            }
        } while (bError);

        System.out.printf("%d/%d = %d",n1,n2, nQuotient);
    }
}

si j'entre un 0 pour le second entier, alors le try / catch fait exactement ce qu'il est censé faire et me fait le remettre. Mais, si j'ai une InputMismatchException comme en entrant 5.5 pour un des nombres, il suffit montre mon message d'erreur dans une boucle infinie. Pourquoi cela se produit - il, et que puis-je y faire? (En passant, j'ai essayé en tapant InputMismatchException que l'argument de l'attraper, mais il n'a pas de résoudre le problème.

18
demandé sur feeling abused and harassed 2012-10-03 08:50:29

7 réponses

Vous devez appeler next(); lorsque vous obtenez le message d'erreur. Aussi, il est conseillé d'utiliser hasNextInt()

       catch (Exception e) {
            System.out.println("Error!");
           input.next();// Move to next other wise exception
        }

avant de lire la valeur entière, vous devez vous assurer que le scanner en a une. Et vous n'aurez pas besoin d'exception comme ça.

    Scanner scanner = new Scanner(System.in);
    int n1 = 0, n2 = 0;
    boolean bError = true;
    while (bError) {
        if (scanner.hasNextInt())
            n1 = scanner.nextInt();
        else {
            scanner.next();
            continue;
        }
        if (scanner.hasNextInt())
            n2 = scanner.nextInt();
        else {
            scanner.next();
            continue;
        }
        bError = false;
    }
    System.out.println(n1);
    System.out.println(n2);

Javadoc de Scanner

quand un scanner lance une InputMismatchException, le scanner ne passera pas le jeton qui a causé l'exception, de sorte qu'il peut être récupéré ou sauté par certains autre méthode.

25
répondu Amit Deshpande 2012-10-04 05:17:03

Vous pouvez aussi essayer

   do {
        try {
            System.out.println("Enter first num: ");
            n1 = Integer.parseInt(input.next());

            System.out.println("Enter second num: ");
            n2 = Integer.parseInt(input.next());

            nQuotient = n1/n2;

            bError = false;
        } 
        catch (Exception e) {
            System.out.println("Error!");
            input.reset();
        }
    } while (bError);
2
répondu Debobroto Das 2012-10-03 05:09:18

une autre option est de définir entrée Scanner = Nouveau Scanner (Système.in); à l'intérieur du bloc d'essai, cela créera un nouvel objet à chaque fois que vous devez entrer de nouveau les valeurs.

2
répondu ron17ro 2014-07-29 11:47:09

Pour suivre debobroto de das de réponse, vous pouvez également mettre après

input.reset();
input.next(); 

j'ai eu le même problème et quand j'ai essayé ce. Complètement fixe.

2
répondu YoMama420 2016-11-19 20:20:34

bError = false déclaration jamais atteint dans le try block, et la déclaration frappé à l'entrée prise, il continue d'imprimer le erreur en boucle infinie.

essayez de l'utiliser de cette façon en utilisant hasNextInt()

catch (Exception e) {
            System.out.println("Error!");
           input.hasNextInt();         
        }

ou utilisez nextLine() couplé Integer.parseInt() pour la prise d'entrée....

Scanner scan = new Scanner(System.in);

int num1 = Integer.parseInt(scan.nextLine());
int num2 = Integer.parseInt(scan.nextLine());
1
répondu Kumar Vivek Mitra 2012-10-03 05:02:08

juste copier / coller votre programme et avait ce résultat:

Error!
Enter first num: 
.... infinite times ....

Comme vous pouvez le voir, l'instruction:

n1 = input.nextInt();

est continuellement en train de lancer L'Exception quand votre double nombre est entré, et c'est parce que votre flux n'est pas effacé. Pour le réparer, suivez la réponse D'AmitD.

1
répondu Hernan Velasquez 2012-10-03 05:03:37

@Limp, votre réponse est juste, il suffit d'utiliser .nextLine () lors de la lecture de l'entrée. Exemple de code:

    do {
        try {
            System.out.println("Enter first num: ");
            n1 = Integer.parseInt(input.nextLine());
            System.out.println("Enter second num: ");
            n2 = Integer.parseInt(input.nextLine());
            nQuotient = n1 / n2;
            bError = false;
        } catch (Exception e) {
            System.out.println("Error!");
        }
    } while (bError);

    System.out.printf("%d/%d = %d", n1, n2, nQuotient);

Lire la description de la raison pour laquelle ce problème a été causé dans le lien ci-dessous. Chercher la réponse, j'ai posté pour le détail dans ce fil. Java homehouse user input issue

Ok, je vais le décrire brièvement. Quand vous avez lu input en utilisant nextInt(), vous avez juste lu la partie nombre mais le caractère ENDLINE était toujours sur le flux. Qui a été la cause principale. Maintenant regardez le code ci-dessus, tout ce que j'ai fait est de lire la ligne entière et de l'analyser , il jette toujours l'exception et le travail de la façon dont vous vous attendiez à ce que cela fonctionne. Le reste du code fonctionne bien.

1
répondu Jimmy 2017-05-23 12:26:00