简体   繁体   中英

Getting String index out of range with for loop in Java

I have a for loop to remove the vowels from a string, but I get an error if the string ends in a vowel. It works if the string doesn't end in a vowel and prints out the results just fine, but if it ever ends with a vowel it will not work and I get the error. How could I fix this?

package program5;

import java.util.Scanner;

public class Disemvoweling {
public static void main(String[] args) {
      Scanner scnr = new Scanner(System.in);

      String phrase;
      System.out.println("Welcome to the disemvoweling utility.");
      System.out.print("Enter your phrase: ");
      phrase = scnr.nextLine();       
      int inputLength = phrase.length();

      for (int i = 0; i < phrase.length(); i++) {
          if (phrase.charAt(i) == 'a') {
              phrase = phrase.replace("a","");
          }
          if (phrase.charAt(i) == 'e') {
              phrase = phrase.replace("e","");
          }
          if (phrase.charAt(i) == 'i') {
              phrase = phrase.replace("i","");
          }
          if (phrase.charAt(i) == 'o') {
              phrase = phrase.replace("o","");
          }
          if (phrase.charAt(i) == 'u') {
              phrase = phrase.replace("u","");
          }
      }
      System.out.println("The disemvolwed phrase is: " + phrase);
      int inputAfter = phrase.length();
      System.out.print("Reduced from " + inputLength + " characters to " + inputAfter + " characters. ");
      double percentage = (double) inputAfter / inputLength * 100; 
      double percentageRounded = (double) percentage % 1;
      System.out.print("Reduction rate of " + (percentage - percentageRounded) + "%");


}

}

The exception is generated by the charAt function:

Throws: IndexOutOfBoundsException - if the index argument is negative or not less than the length of this string.

The problem is that when you execute this code:

phrase = phrase.replace("a","");

you shorten the string. If this happens on the last char of the string the next chartAt generate the index out of range:

 // Now phrase is shorter and i is over the lenght of the string
 if (phrase.charAt(i) == 'e') {
     phrase = phrase.replace("e","");
 }

The solution is continue to the next loop every time that you execute a replace .

   for (int i = 0; i < phrase.length(); i++) {
      if (phrase.charAt(i) == 'a') {
          phrase = phrase.replace("a","");
          continue;  // Continue to the next loop if a has been found
      }
      ....
  }

A shorter solution will use the method replaceAll as follow:

 phrase = phrase.replaceAll("[aeiou]","");

where [aeiou] is the regular expression matching any of the characters a, e, i, o, u

You're overthinking it. You can safely remove the for loop and just replace the characters, like this:

phrase = phrase.replace("a","");
phrase = phrase.replace("e","");
phrase = phrase.replace("i","");
phrase = phrase.replace("o","");
phrase = phrase.replace("u","");

Or even more concisely

phrase = phrase.replace("a","")
               .replace("e","")
               .replace("i","")
               .replace("o","")
               .replace("u","");

Finally, the shortest solution: just use a regexp with replaceAll

phrase = phrase.replaceAll("[aeiou]","");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM