2010-02-26 7 views
2

Hé là! J'essaye de faire une validation de saisie de données mais je n'ai pas été capable de le comprendre. Je reçois une boucle infinie lorsque j'essaie de valider si le premier caractère entré est une lettre. . . .Infinite While Loop en Java

Merci pour votre aide!

public class methods 
{ 
    public static void main(String args[]) throws IOException 
    { 
     String input =""; 
     int qoh=0; 
     boolean error=true; 

     Scanner keyboard = new Scanner (System.in); 

     //while (error) 
     //{ 
      //error=true; 

     while (error==true) 
     { 
      System.out.print("\nEnter Quantity on Hand: "); 
      input = keyboard.nextLine(); 

      if (input.length() <1) 
      { 
       System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500"); 
       error=true; 
       System.out.println(qoh); 
       System.out.println(input); 
      } 
      else 
      { 
       error=false; 
      } 
     } 

     error = true; 

     while (error==true) 
     { 
      if (Character.isLetter(input.charAt(0))) 
      { 
       System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500"); 
       error=true; 
       System.out.println(qoh); 
       System.out.println(input); 
      } 
      else 
      { 
       qoh = Integer.parseInt(input); 
       error=false; 
       } 
      } 
     } 
    } 
+2

note de côté: while (erreur == true) peut s'écrire while (erreur) – basszero

+0

Est-ce un travail à faire? –

Répondre

3

Vous n'avez pas de input = keyboard.nextLine(); dans votre deuxième boucle while.

Vous pouvez refactoriser votre code pour demander uniquement une nouvelle entrée en cas d'erreur. Donc, juste après le sysout 'ERROR ...'

Extra: Je voudrais vraiment faire cela différent. Le 'error = true' au début est un peu déroutant, car il n'y a peut-être pas d'erreur.

Vous pouvez par exemple écrire une méthode appelée tryProcessLine, qui lit l'entrée et renvoie true si ok et false s'il y avait une erreur, et que juste faire quelque chose comme while(!tryProcessLine()){ }

Exemple de travail ci-dessous:

import java.io.IOException; 
import java.util.Scanner; 

public class Methods { 

    private static int qoh; 

    public static void main(String args[]) throws IOException { 

    while (!tryProcessLine()) { 
     System.out.println("error... Trying again"); 
    } 

    System.out.println("succeeded! Result: " + qoh); 

    } 

    public static boolean tryProcessLine() { 

    String input = ""; 

    Scanner keyboard = new Scanner(System.in); 

    System.out.print("\nEnter Quantity on Hand: "); 

    input = keyboard.nextLine(); 

    try { 
     qoh = Integer.valueOf(input); 

     if (qoh < 0 || qoh > 500) { 
      System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500"); 
      return false; 
     } else { 
      return true; 
     } 
    } catch (NumberFormatException e) { 
     System.out.println("\n**ERROR06** - Quantity on hand must be numeric"); 
     return false; 
    } 
    } 
} 
+0

-1: Ce n'est pas la cause de la boucle infinie. La première boucle est conçue pour lire la première ligne non vide alors que je suppose que la deuxième boucle est censée vérifier que cette ligne contient uniquement des caractères numériques (plutôt que de lire une autre ligne d'entrée). – Adamski

+0

Je suppose qu'il veut obtenir une nouvelle entrée lorsque l'erreur dans la deuxième boucle se produit. Sinon, la deuxième boucle ne devrait pas être une boucle. Parce que maintenant, quand il y a une 'erreur' dans la deuxième boucle, aucune nouvelle entrée n'est demandée, et 'error == true' sera toujours vrai ... – Fortega

+0

Je suppose qu'il veut lire la première ligne non vide de entrée et tente de l'analyser en un entier. Je ne pense pas que l'OP nécessite deux boucles du tout. – Adamski

1

La boucle infinie se produit car la deuxième boucle while est en vérifiant plusieurs fois si le premier caractère de la chaîne (input.charAt(0)) est une lettre. En supposant que le résultat de cette vérification est vrai, la boucle ne se terminera jamais.

Votre code pourrait être simplifié à quelque chose comme:

Integer qty = null; 

while (scanner.hasNext() && qty == null) { 
    String line = scanner.next(); 
    try { 
    qty = Integer.parseInt(line); 
    } catch(NumberFormatException ex) { 
    System.err.println("Warning: Ignored non-integer value: " + line); 
    } 
} 

if (qty == null) { 
    System.err.println("Warning: No quantity specified."); 
} 
0

Si elle est un personnage, vous permettez erreur = encore vrai, ce qui est à l'origine de cette boucle pour continuer à jamais, vous n'êtes pas toujours revenir au début et lire une autre ligne.

Voici un code qui fait ce que vous voulez et qui est structuré un peu mieux.

public class ScanInfo { 

    Scanner keyboard = new Scanner(System.in); 

    public ScanInfo(){ 
    String line = getLineFromConsole(); 
    while(null != line && !"quit".equals(line)){ 
     if(isValidInput(line)){ 
     int validNumber = Integer.parseInt(line); 
     System.out.println("I recieved valid input: "+validNumber); 
     }else{ 
     System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500"); 
     } 
     line = getLineFromConsole(); 
    } 

    } 

    private boolean isValidInput(String line){ 
    //basic sanity 
    if(null == line || line.length() < 1){ 
     return false; 
    } 


    try { 
     int number = Integer.parseInt(line); 

     return (number >= 0 && number <= 500); 

    } catch (NumberFormatException e) { 
     return false; 
    } 

    } 


    public static void main(String[] args) { 
    new ScanInfo(); 

    } 

    public String getLineFromConsole(){ 
    System.out.print("\nEnter Quantity on Hand: "); 
    return keyboard.nextLine(); 

    } 

} 
+0

Pourquoi analyser l'entrée en entier deux fois? – Adamski

+0

"quit"! = Ligne doit être! "Quitter" .equals (ligne) – Fortega

+0

J'analyse l'entier deux fois parce que je suis paresseux et encapsulé mal. Fortega: a fait votre changement. – Kylar

1

Le problème est dans cette section:

     while (error==true) 
         { 
          if (Character.isLetter(input.charAt(0))) 
          { 
           System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500"); 
           error=true; 
           System.out.println(qoh); 
           System.out.println(input); 
          } 
          else 
          { 
           qoh = Integer.parseInt(input); 
           error=false; 
          } 
         } 

Une fois que vous avez une lettre dans la première position, cette boucle ne peut jamais se terminer. Il vérifie si une lettre est dans la première position (c'est), l'imprime et répète. Essayez de changer:

      while (error==true) 
          { 
           if (Character.isLetter(input.charAt(0))) 
           { 
            System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500"); 
            error=false; 

            ... 

En outre, deux autres:

while (error == true) peut être raccourci à while(error).

De plus, Integer.parseInt lancera un NumberFormatException si l'entrée n'est pas un nombre entier - vous devez attraper et gérer ceci.

Aussi, pourquoi avez-vous besoin de la deuxième boucle du tout? Il semble que ce soit seulement supposé valider l'entrée - si c'est le cas, vous pouvez déplacer cette logique dans la première boucle et éliminer la seconde. N'utilisez les boucles que pour les choses qui devraient arriver de façon répétée (comme l'utilisateur qui entre les données d'entrée). Il n'est pas nécessaire de vérifier la même entrée plusieurs fois.