2011-09-13 1 views
0

J'ai le code suivant qui lit les données d'un fichier et les stocke dans une variable String, maintenant quand je l'exécute, il me donne une exception de chaîne hors limites. Comment puis-je corriger cette erreur?Pourquoi est-ce que je reçois une exception String out of bounds

commande d'exécution et d'erreur:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1882 
    at java.lang.String.charAt(String.java:694) 
    at IfCounter2.main(IfCounter2.java:92) 
Code

:

import java.io.*; 

public class IfCounter2 
{ 
    // method to check if there is a single-line comment 
    public static boolean lineAComment(String line) 
    { 
     if (line.contains("//")) 
      return true; 

     return false; 
    } 

    // method to check if there is a multi-line comment start 
    public static boolean multiLineCommentStart(String line) 
    { 
     if (line.contains("/*")) 
      return true; 

     return false; 
    } 

    // method to check if there is a multi-line comment end 
    public static boolean multiLineCommentEnd(String line) 
    { 
     if (line.contains("*/")) 
      return true; 

     return false; 
    } 

    public static void main(String[] args) throws IOException 
    { 
     // variable to keep track of ifs 
     int ifCount = 0; 
     // check how many arguments are passed 
     int numArgs = args.length; 

     // look at all the arguments 

     // they don't want to count ifs in comments ************************************ --nocomment was entered 
     if (args[0].equals("--nocomments")) 
     { 
      // create a new BufferReader for the file that will be at args 1 
      BufferedReader reader = new BufferedReader(new FileReader (args[1])); 
      String line = null; 
      StringBuilder stringBuilder = new StringBuilder(); 
      String ls = System.getProperty("line.separator"); 

      // read from the text file 
      boolean multiLineComment = true; 

      // ignore comments as we store data in a String variable 
      while ((line = reader.readLine()) != null) 
      { 
       if (!multiLineCommentStart(line)) 
       { 
        multiLineComment = true; 
       } // end if 

       if (multiLineComment) 
       { 
        if (!multiLineCommentEnd(line)) 
        { 
         multiLineComment = false; 
        } // end if 
       } // end if 

       if (!lineAComment(line) && !multiLineComment) 
       { 
        stringBuilder.append(line); 
        stringBuilder.append(ls); 
       } // end if 
      } // end while 

      // create a new string with stringBuilder data 
      String tempString = stringBuilder.toString(); 
      System.out.println(tempString); 

      // create one last string to look for our valid if(s) in, 
      // with ALL whitespace removed 
      String compareString = tempString.replaceAll("\\s",""); 
      //System.out.println(compareString); 

      for (int i = 0; i < compareString.length(); i++) 
      { 

       if (compareString.charAt(i) == ';' || compareString.charAt(i) == '}' || compareString.charAt(i) == '{' || compareString.charAt(i) == '\n') 
       { 
        i++; 

        if (compareString.charAt(i) == 'i') 
        { 
         i++; 

         if (compareString.charAt(i) == 'f') 
         { 
          i++; 

          if (compareString.charAt(i) == '(') 
           ifCount++; 
         } // end if 
        } // end if 
       } // end if 

      } // end for 

     } // end if (comments option) 

     // else ******************************************************** count ifs as usual 
     /*else 
     { 
      for (int c = 0; c <= numArgs; c++) 
      { 
       // create a new BufferReader 
       BufferedReader reader2 = new BufferedReader(new FileReader (args[c])); 
       String line2 = null; 
       StringBuilder stringBuilder2 = new StringBuilder(); 
       String ls2 = System.getProperty("line.separator"); 

       // read from the text file 
       while ((line2 = reader2.readLine()) != null) 
       { 
        stringBuilder2.append(line2); 
        stringBuilder2.append(ls2); 
       } 

       // create a new string with stringBuilder data 
       String tempString2 = stringBuilder2.toString(); 

       // create one last string to look for our valid if(s) in 
       // with ALL whitespace removed 
       String compareString2 = tempString2.replaceAll("\\s",""); 

       // check for valid if(s) 
       for (int i = 0; i < compareString2.length(); i++) 
       { 
        if (compareString2.charAt(i) == ';' || compareString2.charAt(i) == '}' || compareString2.charAt(i) == '{') // added opening "{" for nested ifs :) 
        { 
         i++; 

         if (compareString2.charAt(i) == 'i') 
         { 
          i++; 

          if (compareString2.charAt(i) == 'f') 
          { 
           i++; 

           if (compareString2.charAt(i) == '(') 
            ifCount++; 
          } // end if 
         } // end if 
        } // end if 

       } // end for 
      } // end if (else option) 
     } // end for 
*/  
     // print the number of valid "if(s) with a new line after" 
     System.out.println(ifCount + "\n"); 

    } 
} 
+1

Avez-vous essayé d'utiliser un débogueur et de définir un point d'arrêt à la ligne 92? De là, vous pouvez inspecter les variables et déterminer précisément pourquoi l'index que vous passez à 'charAt' n'est pas valide. –

+0

quelle ligne de code se trouve à la ligne 92? –

+0

Je ne suis pas sûr de savoir quel est le but de ce code, mais il est évidemment incorrect. S'il doit analyser le code Java, vous ne pouvez pas reconnaître if (true); si (faux); sur une ligne comme deux ifs;) vous compterez juste pour un. –

Répondre

5
for (int i = 0; i < compareString.length(); i++) 
     { 

      if (compareString.charAt(i) == ';' || compareString.charAt(i) == '}' || compareString.charAt(i) == '{' || compareString.charAt(i) == '\n') 
      { 
       i++; 

       if (compareString.charAt(i) == 'i') 

Le code ci-dessus est votre problème. Notez que i0 - (longueur - 1) ce qui signifie que charAt (i) est ok. Cependant, alors vous faites i ++ et faites une autre charAt (i). Ainsi, lorsque i == longueur -1, charAt après i ++ entraînera une exception.

+0

Comment puis-je résoudre ce problème? Je dois regarder à travers tous les caractères de la chaîne. – josh

+0

vous pouvez vérifier que ** i

+1

Comparez i à la longueur de la chaîne après l'avoir incrémentée d'une façon. (if (compareString.length() <= i) break;) Un meilleur moyen serait d'avoir votre boucle principale uniquement sur compareString.length() - 3 (puisque le contenu de la boucle n'est pas pertinent vers la fin) . – Rontologist

0

Vous avez un tas de problèmes dans votre code. Par exemple. quand vous faites des choses comme ceci:

if (compareString.charAt(i) == 'i') 
    { 
     i++; 

     if (compareString.charAt(i) == 'f') 
     { 

vous vous tirez dans le pied. Quand je pointe vers le dernier caractère ici, vous obtiendrez une erreur dans le 2e si. Je déconseille fortement ce type de vérification «si» imbriquée pour ce que vous essayez de faire. Cela peut être une source infinie de bugs dans votre code. Jetez un coup d'œil à l'instruction "switch":

switch(compareString.charAt(i)) { 
    case 'i': 
     // do something 
     break; 
    case 'f': 
     // do something else 
     break; 
} 
1

Votre boucle for échoue par défaut. Si vous atteignez ';' à la fin de la ligne, par exemple: «if (true); vous incrémentez ensuite i et testez si le prochain caractère n'est pas 'i' ... ce qui jette évidemment l'exception OoB lorsque vous posez des questions sur l'index supérieur à string.length - 1;

Questions connexes