问题
I am trying to read in a string from a file, extract individual characters and use those characters to fill a 2D char array. So far I have been able to do everything except fill the array. I keep getting an Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: error message. Any help would be appreciated. This is my first time working with 2D arrays. Thanks. Here are the contents of the test.txt. Each word on a new line. The first 2 integers are the dimensions of the array 4 4 FILE WITH SOME INFO
public class acsiiArt
{
public static void main(String[] args) throws IOException
{
File file = new File("test.txt");
Scanner inputFile = new Scanner(file);
int x = inputFile.nextInt();
int y = inputFile.nextInt();
while (inputFile.hasNext())
{
char [][] array = new char [x][y];
//char c = words.charAt(i);
for (int row =0; row<x;row++)
{
for (int col =0; col<y;col++)
{
String words = inputFile.nextLine();
for (int i=0; i<words.length(); i++)
array[x][y]=words.charAt(i);
}
}
}
}
}
回答1:
for (int row =0; row<x;row++)
{
for (int col =0; col<y;col++)
{
String words = inputFile.nextLine();
for (int i=0; i<words.length(); i++)
array[x][y]=words.charAt(i);
}
}
The total number of indices in array is x * y. Below, you are filling all the possible indices
for (int row =0; row<x;row++)
{
for (int col =0; col<y;col++)
So when you add this:
for (int i=0; i<words.length(); i++)
you multiplying another factor words.length. So you need x * y * words.length number of indices, but you only have x * y. Thats why you're getting ArrayIndexOutOfBoudsException
回答2:
I've seen problems like this and I'm assuming that x and y are being initialized to the first two characters which represent the number of rows and the number of columns. If that is the case, then third for loop for (int i=0; i<words.length(); i++) is unnecessary. You can just reffer to the col variable for the word at that point, since it should represent how many characters there are.
All of this is only applicable if the chars are in a rectangular pattern, meaning that there are the same number of columns in every row. Otherwise you will get an IndexOutOfBoundsError as soon as one of the lines is shorter than the the column value initially given.
Edit: If you're final 2d char array is not meant to be rectangular and instead "jagged," a different implementation is required. I'd recommend either a 2d arrayList (an arrayList of arrayLists).
Or you can keep your current implementation with the third for loop, but you have to be sure that the original x value represents the longest row/most amount of columns, and then you'd be able to deal with each row indivually with words.length. You'd also have to be fine with the extra portions of the lines that have a length>x having spaces initialized to null.
回答3:
ArrayIndexOutOfBoundsException means you are using array beyond its limit. So in your case:
char [][] array = new char [x][y];
//char c = words.charAt(i);
for (int row =0; row<x;row++) {
for (int col =0; col<y;col++){
String words = inputFile.nextLine();
for (int i=0; i<words.length(); i++)
array[x][y]=words.charAt(i);
}
}
Problem may be because your array size is less then input words. problem is because you are putting extra loop, and your loop it self is not correct. Please seen code below.
So you can do 2 things.
- change value of
ylarge enough so that any word string can store. - rather than looping on size of word you can loop on your array size like.
.
for (int row =0; row<x;row++) {
String words = inputFile.nextLine();
int size = Math.min(words.length(),y);
for (int i=0; i< size; i++)
array[row][i]=words.charAt(i);
}
回答4:
The easiest way to do this is with an ArrayList<char[]>. All you have to do is add a new char[] for each new line read:
ArrayList<char[]> chars = new ArrayList<>();
while (inputFile.hasNext()){
chars.add(inputFile.nextLine().toCharArray());
}
char[][] array = chars.toArray(new char[chars.size()][]);
An ArrayList is basically an array of changeable size. This code takes each line in the file, turns it into a char[], then adds it to the ArrayList. At the end, it converts the ArrayList<char[]> into a char[][].
If you can't or don't want to use ArrayList, you could always do this:
char[][] array = new char[1][];
int a = 0;
while(inputFile.hasNext()){
//read line and convert to char[]; store it.
array[a] = inputFile.nextLine().toCharArray();
//if there are more lines, increment the size of the array.
if (inputFile.hasNext()){
//create a clone array of the same length.
char[][] clone = new char[array.length][];
//copy elements from the array to the clone. Note that this can be
//done by index with a for loop
System.arraycopy(array, 0, clone, 0, array.length);
//make array a new array with an extra char[]
array = new char[array.length + 1][];
//copy elements back.
System.arraycopy(clone, 0, array, 0, clone.length);
a++;
}
}
If you know the dimensions of the array beforehand:
char[][] array = new char[dimension_1][];
int a = 0;
while (inputFile.hasNext()){
array[a] = inputFile.nextLine().toCharArray();
a++; //don't need to check if we need to add a new char[]
}
In response to comment:
We know that a char[][] cannot be printed with Arrays.toString() (if we want the contents) because we will get a lot of char[].toString(). However, a char[][] can be printed with one of the following methods:
public static String toString(char[][] array){
String toReturn = "[\n";
for (char[] cArray: array){
for (char c: cArray){
toReturn += c + ",";
}
toReturn += "\n";
}
return toReturn + "]";
}
I personally prefer this one (requires import java.util.Arrays):
public static String toString(char[][] array){
String toReturn = "[\n";
for (char[] cArray: array){
toReturn += Arrays.toString(cArray) + "\n";
}
return toReturn + "]";
}
来源:https://stackoverflow.com/questions/19649807/2d-char-array-from-a-file