4

I have to read a text file into a 2d Array.

The only problem I am having, is the width of the array varies, with a maximum size of 9 columns. I don't know how many rows there will be.

Some lines will have 6 columns for example, and some will have 9.

here is a small section of my CSV file:

1908,Souths,Easts,Souths,Cumberland,Y,14,12,4000
1909,Souths,Balmain,Souths,Wests,N
1910,Newtown,Souths,Newtown,Wests,Y,4,4,14000
1911,Easts,Glebe,Glebe,Balmain,Y,11,8,20000
1912,Easts,Glebe,Easts,Wests,N
1913,Easts,Newtown,Easts,Wests,N

and here is my code so far

    import java.io.*;
import java.util.*;

public class ass2 {

    public static void main(String[] args) throws IOException {
        readData();

    }

    public static void readData() throws IOException{
        BufferedReader dataBR = new BufferedReader(new FileReader(new File("nrldata.txt")));
        String line = "";

        ArrayList<String[]> dataArr = new ArrayList<String[]>(); //An ArrayList is used because I don't know how many records are in the file.

        while ((line = dataBR.readLine()) != null) { // Read a single line from the file until there are no more lines to read

            String[] club = new String[9]; // Each club has 3 fields, so we need room for the 3 tokens.

            for (int i = 0; i < 9; i++) { // For each token in the line that we've read:
                String[] value = line.split(",", 9);                
                club[i] = value[i]; // Place the token into the 'i'th "column"
            }

            dataArr.add(club); // Add the "club" info to the list of clubs.
        }

        for (int i = 0; i < dataArr.size(); i++) {
            for (int x = 0; x < dataArr.get(i).length; x++) {
                System.out.printf("dataArr[%d][%d]: ", i, x);
                System.out.println(dataArr.get(i)[x]);
            }
        }
    }

The error I get is:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at ass2.readData(ass2.java:23)
at ass2.main(ass2.java:7)

Can someone please help :'(

Thank you!

1
  • 1
    Which is line 49 of your code? Also, you should move the line String[] value = line.split(",", 9); to be before the loop. Commented May 28, 2013 at 4:46

4 Answers 4

10

You can use OpenCSV for read the CSV file.

// Read all
CSVReader csvReader = new CSVReader(new FileReader(new File("nrldata.txt")));
List<String[]> list = csvReader.readAll();

// Convert to 2D array
String[][] dataArr = new String[list.size()][];
dataArr = list.toArray(dataArr);
Sign up to request clarification or add additional context in comments.

2 Comments

This makes things really easy, I like this better than the accepted answer.
what should we import?
3

The problem is with your inner loop. You are trying to access 9 elements of value regardless of how many values there are on the line. First, you should move the assignment to value to be before the inner loop. Then, you need to limit the loop iterations to the minimum of 9 and the length of value:

String[] value = line.split(",", 9);                
int n = Math.min(value.length, data.length);
for (int i = 0; i < n; i++) { // For each token in the line that we've read:
    data[i] = value[i]; // Place the token into the 'i'th "column"
}

Note that the trailing elements of data will be null.

2 Comments

Actually, you don't need the "minimum" part, since you pass '9' as the second argument to split().
@ExpertSystem - That's true. It's kind of a belt-and-suspenders thing, in case the code evolves and data somehow ends up being possibly shorter than 9 (perhaps inadvertently). A symbolic constant would be better here rather than having the literal 9 scattered all over the code.
1

You get the error, because you try to access a 7th token (index 6) on a line that contains only 6. Replace that:

for (int i = 0; i < 9; i++) { // For each token in the line that we've read:
    String[] value = line.split(",", 9);                
    data[i] = value[i]; // Place the token into the 'i'th "column"
}

with this:

String[] value = line.spkit(",", 9);   // Split the line into max. 9 tokens
for (int i = 0; i < value.length; i++) {
    data[i] = value[i];   // Add each token to data[]
}

You could, in fact, replace the whole while-loop body with this one-liner:

dataArr.add(Arrays.copyOf(line.split(",", 9), 9));

See, also, this short demo.

1 Comment

This should have been marked as the answer! Nice one @gkalpak
0

Instead of array, you can use ArrayList of List. As List is dynamically growable so you do't need to think of it size either.

List<List<String>> dataArr = new ArrayList<List<String>>();

and

while ((line = dataBR.readLine()) != null){ 
        for (int i = 0; i < 9; i++) 
            dataArr.add(Arrays.asList(line.split(",", 9)));                
}

2 Comments

thats not a solution for ArrayIndexOutofBound, still if he uses wrong index, he may still end up getting same exception
I have proposed a better solution, I think you got me wrong :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.