4

I am desperately trying to figure out a way of stopping "String index out of range: 0" errors... It happens whenever I don't enter anything and then continue execution:

static String getRef(Scanner Keyboard)
{
    Scanner keyboard = new Scanner(System.in);        
    String ref= "";        
    boolean valid = false;
    int errors = 0;
    boolean problem = false;

    while(valid==false)
    {
        System.out.println("Please enter a reference number which is two letters followed by three digits and a letter(B for business accounts and N for non business accounts)");
        ref = keyboard.nextLine();

        for (int i=0; i<6; i++)
        {   
            if (ref.charAt(i)=='\0')            
            {
                problem = true;
            }                
        } 

        if(problem == true)
        {
            System.out.println("The reference must consist of 6 Characters");
        }
        else
        {             
            if ((Character.isDigit(ref.charAt(0))== true) || (Character.isDigit(ref.charAt(1))== true))
            {
                System.out.println("The first 2 characters must be letters");
                errors = errors + 1;
            }

            if ((Character.isDigit(ref.charAt(2))== false) || (Character.isDigit(ref.charAt(3))== false)||(Character.isDigit(ref.charAt(4))== false))
            {
                System.out.println("The 3rd,4th and 5th characters must be numbers");
                errors = errors + 1;
            }

            if ((!ref.toUpperCase().endsWith("B"))&&(!ref.toUpperCase().endsWith("N"))) 
            {
                System.out.println("The 6th character must be either B(for business accounts) or N(for non business accounts) ");
                errors = errors + 1;
            }

            if (errors==0)
            {
                valid=true;
            }
        }

    }        
    return ref;        
}

What I want is to be able to output an error message if the string does not contain a character at a certain index e.g. ref.charAt(0).

This will help (example):

if(ref.charAt(aNumber)==null) { 
    // display error message 
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 2
    Why did you use 6. Can't you just use string.length for same and do your logical manipulations there after. – Vinay Prajapati Jan 03 '16 at 03:59
  • 2
    Possible duplicate of [Java - "String index out of range" exception](http://stackoverflow.com/questions/6319089/java-string-index-out-of-range-exception) – Vinay Prajapati Jan 03 '16 at 04:01
  • 1
    Why are you checking keyboard input for `'\0'`? `String`s aren't null-terminated in Java. – Olathe Jan 03 '16 at 04:21

2 Answers2

4

Your problem is here:

ref.charAt(i)=='\0'

What happens if ref is a zero length string? In that case, trying to access the character at index 0 (where the first character would normally be) will give you your index out of range: 0 error. Make sure you test the string length first:

if (ref != null && !ref.isEmpty() &&ref.charAt(i)=='\0')  { .. }
Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
3

Adding a length() check

ref is empty (that is "") when you don't enter anything. So you can't get the character at 0 (or 1, 2, 3 ...). You can add an if check on the length, something like

if (ref.length() > 5) {
    for (int i = 0; i < 6; i++) {   
        if (ref.charAt(i) == '\0') {
            problem = true;
        }                
    } 
} else {
    System.out.println("Please enter at least 6 characters");
}

Regular Expression

It might be simpler to compile a (reusable) Pattern with a regular expression to validate your reference criteria (2 letters, followed by 3 digits, followed b or n). Something like,

String ref; // <-- get input
Pattern p = Pattern.compile("([a-zA-Z]{2})(\\d{3})([B|N|b|n])");
Matcher m = p.matcher(ref);
if (m.matches()) { // <-- valid = m.matches();
    System.out.println("ref is valid");
} else {
    System.out.println("ref is not valid");         
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    Well, I wouldn't use `\\D{2}` to validate letters ... :P – Tom Jan 03 '16 at 03:56
  • If OP wants to accept only latin letters, then this is ok, but if he likes to accept more types of letters, then `Pattern` provides `\p{L}`, which accepts every Unicode letter. – Tom Jan 03 '16 at 04:05