2

I wrote a program for class with the following requirements:

Prompt a use to enter a new password. Must be five characters in length. Must have one upper case letter. Must have one lower case letter. Must have one digit.

If any of those conditions were not met, the output had to state the error. If all conditions were met, output "password successfully changed," or something similar. The problem arose when I discovered that I could not use the for loop in my program, since we are only supposed to use what we have learned up until now to work on our ingenuity and problem solving. It was also specifically stated that we could not use arrays. I started my program over from scratch, and everything worked, up until I purposely entered four characters to output "must have five characters." I got the string index out of bounds exception error that showed my charAt(4) being the culprit. It is my understanding that if I typed 4 characters, the program thinks a fifth character doesn't exist. Why is it showing this error even though I stated the length condition below the list of chars? Pseudocode will suffice since I prefer learn from guidance rather than copying code. It has to be something small that I'm looking over, because everything works except typing too few characters. It shows the same error, just changes the index in relation to how many characters are missing.
Here is the program:

import java.util.Scanner;

public class ChangePassword1 {
  public static void main(String[]args) {

    Scanner input = new Scanner(System.in);

    boolean hasUpper = false;
    boolean hasLower = false;
    boolean hasDigit = false;
    boolean passLength = false;

    System.out.print("Please enter your new password: ");
    String newpassword = input.nextLine();

    char c1 = newpassword.charAt(0);
    char c2 = newpassword.charAt(1);
    char c3 = newpassword.charAt(2);
    char c4 = newpassword.charAt(3);
    char c5 = newpassword.charAt(4);

    if (newpassword.length() < 5 || newpassword.length() > 5) {
      System.out.println("Your password must be five characters in length.");

    }

    if (!Character.isUpperCase(c1) && !Character.isUpperCase(c2) && !Character.isUpperCase(c3) && !Character.isUpperCase(c4) && !Character.isUpperCase(c5)) { 
      System.out.println("Your password must contain at least one uppercase letter.");

      if (!Character.isLowerCase(c1) && !Character.isLowerCase(c2) && !Character.isLowerCase(c3) && !Character.isLowerCase(c4) && !Character.isLowerCase(c5)) 
        System.out.println("Your password must contain at least one lowercase letter.");

      if (!Character.isDigit(c1) && !Character.isDigit(c2) && !Character.isDigit(c3) && !Character.isDigit(c4) && !Character.isDigit(c5)) 
        System.out.println("Your password must contain at least one digit.");
    }


    if (newpassword.length() == 5) {
      passLength = true;

      if (Character.isUpperCase(c1) || Character.isUpperCase(c2) || Character.isUpperCase(c3) || Character.isUpperCase(c4) || Character.isUpperCase(c5))
        hasUpper = true;
      if (Character.isLowerCase(c1) || Character.isLowerCase(c2) || Character.isLowerCase(c3) || Character.isLowerCase(c4) || Character.isLowerCase(c5))
        hasLower = true;
      if (Character.isDigit(c1) || Character.isDigit(c2) || Character.isDigit(c3) || Character.isDigit(c4) || Character.isDigit(c5))
        hasDigit = true;
      if (passLength == true && hasUpper == true && hasLower == true && hasDigit == true) 
        System.out.println("Password successfully changed.");
    }
  }
}
Andy Brown
  • 18,961
  • 3
  • 52
  • 62
DevOpsSauce
  • 1,319
  • 1
  • 20
  • 52
  • Did my answer help? If so please consider [accepting it](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) using the check mark. This indicates to the wider community that it was a helpful answer and gives some reputation to both the answerer and yourself. I notice you have asked several questions since joining, but [not marked any of the answers as accepted](http://stackoverflow.com/search?q=user%3A4522447+is%3Aquestion+hasaccepted%3Ano) - you should get into the habit of accepting the best answer to your problem. – Andy Brown Feb 27 '15 at 14:28
  • Thanks. Still getting used to the site. I completely overlooked that. – DevOpsSauce Feb 28 '15 at 21:15

2 Answers2

4

If you look at this block you might see the error:

char c1 = newpassword.charAt(0);
char c2 = newpassword.charAt(1);
char c3 = newpassword.charAt(2);
char c4 = newpassword.charAt(3);
char c5 = newpassword.charAt(4);

if (newpassword.length() < 5 || newpassword.length() > 5) {
    System.out.println("Your password must be five characters in length.");

}

You test to see that you have a string with 5 characters after you try and access the 5th character with charAt(4). Try moving the test before the charAt calls: that will prevent you calling charAt for String indexes that don't exist.

Also, your test could be simpler. If it has to be 5 characters, why not just test to see if newPassword.length() is equal to (==) the correct length?

Andy Brown
  • 18,961
  • 3
  • 52
  • 62
  • When I put the test before the charAt calls, it prints the "must be 5 characters" message, but it also gives me the out of bounds exception (index out of range: 4). – DevOpsSauce Feb 19 '15 at 03:03
  • @csheridan. Yes. You'll need to return from the program if it isn't 5 characters (you did say I shouldn't give you the complete answer, just some guidance). – Andy Brown Feb 19 '15 at 03:05
  • this may sound silly, but I don't think I can technically use that method, since it hasn't been "learned" yet. That is in a later chapter. – DevOpsSauce Feb 19 '15 at 03:09
  • @csheridan. You mean `return`? If so then just use an `if` equals (`==`) `5` and wrap the rest of the program in that. – Andy Brown Feb 19 '15 at 03:11
0

After many errors and pitfalls, this was the only way the out of bounds exception would go away, the return; statement.

    System.out.print("Please enter your new password: ");
    String newpassword = input.nextLine();

    if (newpassword.length() != 5) { 
       System.out.println("Your password must be five characters in length.");
      return;
    } 
DevOpsSauce
  • 1,319
  • 1
  • 20
  • 52