Broken charAt() loop

392 views Asked by At

I have been asked to do the following:

Alter introductory problem 1 to display the entered names in alphabetical order by last name. Problem 1: Write a program that creates a 5 x 2 array. The first column represents first names and the second column will store last names. Have the user enter 5 full(first and last) names to be stored in this 2D array. After all input is taken, display the names, but show them as LastName, first initial.

I now realize that the method outlined below is not the proper/most efficient way to attack this program, but I'm still baffled as to why the program fails in the way in does. When I run the program in eclipse, it prints the line of question marks once and then throws the following exception:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0 at java.lang.String.charAt(Unknown Source) at TwoD6.main(TwoD6.java:36)

It seems to be failing the second time it runs, and I can't understand why this is. I've tried changing it between variable types, fearing that the the numeral value of the char wasn't accepted (the charAt command was originally in the if statement), as well as filling the array before the user does (thinking that perhaps the error came from java not accepting that the strings would have characters at position 0).


import java.util.Scanner;

public class TwoD6 {    

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("Input 5 full names (first and last).");
    String [][] d2 = { { " "," " },
            {" "," "},
            {" "," "},
            {" "," "},
            {" "," "} };
            //new String[5][2]; initial string declaration, which I previously thought could be the source of the issues
    for(int i = 0; i < d2.length; i++)
    {
        d2 [i][0] = sc.next();
        d2 [i][1] = sc.next();
    }

    for(int i = 0; i < d2.length-1; i++)
    {
        char c = d2[i][1].charAt(0);
        char d = d2[i+1][1].charAt(0);

        int e = c; int f = d;
        if(e < f)
        {
            System.out.println("????????????????"); //implemented to see how many times the loop runs; currently prints once
            String a = ""; String b = ""; //switchers
            d2[i][0] = a; d2[i][1] = b;
            d2[i][0] = d2[i+1][0]; d2[i+1][0] = a;
            d2[i][1] = d2[i+1][1]; d2[i+1][1] = b;
        }
    }
    for(int i = 0; i < d2.length; i++) //printing the array
    {
        char firstChar = d2[i][0].charAt(0); 
        System.out.println(d2[i][1] + ", " + firstChar + ".");
    }

 }

} 

I would appreciate any explanations you could give me. I'm not really interested in fixing this in terms of making it a viable solution to the problem set, as I've already coded a better program, but I'd like to know what went wrong here with the charAt() commands and how to fix it for next time. Thanks!

3

There are 3 answers

0
vivek On BEST ANSWER

The code in "if-block" in second "for" loop will store a zero length string at next index in your 2 -d array, this will cause exception in very next iteration

The real problem is following set of lines (in second for loop's if block )

   if(e < f)
    {
        System.out.println("????????????????"); //implemented to see how many times the loop runs; currently prints once
        String a = ""; String b = ""; //switchers
        d2[i][0] = a; d2[i][1] = b;
        d2[i][0] = d2[i+1][0]; d2[i+1][0] = a;
        d2[i][1] = d2[i+1][1]; d2[i+1][1] = b;
    }

Most precisely lines

         d2[i][0] = a; d2[i][1] = b;
         d2[i+1][0] = a;  // THIS ONE WILL CAUSE PROBLEM IN NEXT ITERATION
         d2[i+1][1] = b; // THIS ONE WILL CAUSE PROBLEM IN NEXT ITERATION

since a="" ,b ="" The value of d2[i+1][0] and d2[i+1][1] is nothing but a zero length String . Which doesn't have any character at next index in loop

You can test it your self by adding following line in beginning and end of second for loop in your code and see the output

 System.out.println(i+"  "+d2[i][0]+" ---- "+d2[i+1][0]);

Here is what i got

   Input 5 full names (first and last).
   as gh
   qe fg
   er ty
   df gr
   yp dfg
   0  as ---- qe
   0 as ---- qe   //end of 0th loop
   1  qe ---- er
   ???????????????? //if block executed in 1st loop
   1 er ----     // end of loop notice value at index 2 is blank now
   2   ---- df   // Now we'll have exception in this line
    Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.lang.String.charAt(String.java:686)
    at javaapplication7.Main.main(Main.java:33)

[EDIT] Also this code doesn't solve the problem you are trying to solve even after you have fixed this bug. As there are lot of logical errors with this code

0
PNS On

Without the actual input data one can only guess.

At a first glance, the offending code line seems to be

char firstChar = d2[i][0].charAt(0); 

in the last for loop.

Apparently the string where the error occurs is empty, so trying to call charAt(0) (i.e., trying to read the first character) throws a StringIndexOutOfBoundsException, because the empty string does not have any characters to read.

In other words, you probably don't supply enough input, so the d2 array is not filled up, leaving some values set to the empty string.

0
MxLDevs On

The error means that you are trying to access a character that is outside of the range of the string. This is possible if the size of the string is 0 (eg: the empty string). charAt(0) would fail here because it tries to access the first character, which doesn't exist.

In general, if you ever index into a string, but you are not guaranteed whether the string may be empty or not, one way to handle it is to first check whether it is a "valid" string, before trying to access the character. For example

// Check if it actually has characters before accessing it
if (d2[i][0].length() > 0) {
   //access the string
}