Работаю над заданием, где я должен читать данные из файла в массив, чтобы выполнить некоторые демонстрации поиска/сортировки.
public class A5 {
public static void main(String[] args) throws FileNotFoundException, IOException {
fileToArray();
}
/**
* populates array from file
* @throws IOException
* @throws FileNotFoundException
*/
public static <T extends Comparable<T>> void fileToArray() throws IOException, FileNotFoundException {
int FileIndex = 0;
A5GItem[] gItems = new A5GItem[5150];
File file = new File("GroceryData.txt");
Scanner inputFile = new Scanner(file);
while (inputFile.hasNext()) {
String line = inputFile.nextLine().replace(" oz", "").replace("«", "");
String[] tokens = line.split(";");
if (tokens.length == 5) {
System.out.println(tokens[0]);
System.out.println(tokens[1]);
System.out.println(tokens[2]);
System.out.println(tokens[3]);
System.out.println(tokens[4]);
System.out.println(FileIndex);
FileIndex++;
else {
System.out.println("Bad line: " + line);}
} }`
Я попытался проверить, правильно ли я заполнил массив, зациклив некоторые операторы println. Он правильно токенизирует первые 400 (примерно) элементов в списке, а затем печатает только половину последнего токена и выдает
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at A5.fileToArray(A5.java:59)
at A5.main(A5.java:16)
после того, как пробежался с этим индексом для многих итераций. Не знаю, с чего начать устранение неполадок.
Я предполагал, что строка над ней устанавливает границы, учитывая, что никогда не бывает более 5 токенов.
Позаботьтесь о соглашении об именах Java. Имена переменных должны начинаться с символов нижнего регистра.
Напечатайте line напрямую, это должно стать хорошим началом для устранения этой проблемы.
Для чего вы используете FileIndex? Поскольку вы используете сканер, hasNext выполняется построчно. И, как написал @Jens: нотация в верблюжьем регистре. Нет переменных, начинающихся с верхнего регистра. А что такое строка 59 в вашем случае?
@AlexanderFalk Я использовал эту переменную для некоторых более поздних шагов, я не заполнил общий массив токенами.
Инициализация токенов в tokens = new String[5]; является избыточной и не гарантирует, что ваш массив токенов будет состоять из пяти элементов. Скорее вы должны написать if (tokens.length == 5) { do your stuff } else { System.out.println("Bad line: " + line)}
@PushpeshKumarRajwanshi Обновлено. Я до сих пор не могу найти, что отделяло эту строку файла от следующей. Речь идет о строке Beech-Nut Stage 2;Mixed Vegetables;4 oz;5.67;6047, где последний токен заканчивается на Vegeta. Список перед этим выглядит как Beech-Nut Stage 2;Pears & Pineapple;4 oz;7.27;6031 Beech-Nut Stage 2;Pears & Raspberries;4 oz;8.83;5731 Beech-Nut Stage 2;Butternut Squash;4 oz;1.39;5932 Beech-Nut Stage 2;Corn & Sweet Potatoes;4 oz;5.12;5796 Beech-Nut Stage 2;Country Garden Vegetables;4 oz;10.04;6046 для сравнения




Очевидно, что одна из строк в файле "GroceryData.txt" не содержит 5 токенов. Обратите внимание, что метод split() возвращает массив, размер которого не может быть равен 5. Поэтому инициализация переменной tokens не требуется. Кажется, что переменная FileIndex подсчитывает прочитанные строки, поэтому я предлагаю распечатать ее, а также напечатать размер массива tokens после split(), например.
while (inputFile.hasNext()) {
String line = inputFile.nextLine().replace(" oz", "").replace("«", "");
String[] tokens = line.split(";");
FileIndex++;
System.out.println("Line: " + FileIndex + " has " + tokens.length + " tokens.");
}
Затем вы обнаружите, какая строка файла не соответствует вашим ожиданиям.
Кстати, что касается соглашения об именах, которое упоминают комментаторы, это просто соглашение. Это не то, что вызывает ваш ArrayIndexOutOfBoundsException
Также опубликованная вами трассировка стека указывает на то, что строка 59 вашего кода содержит проблему. Я думаю, что это была бы эта линия...
System.out.println(tokens[2]);
Печать элементов массива предполагает, что он содержит 5 элементов, но, как я и другие упоминали, метод split() может не возвращать массив из 5 элементов.
Сначала попробуйте то, что я предложил. Вам нужно отладить свой код, а не просто пройтись по нему. Я предложил простой способ определить, что может быть причиной Exception.
Поиск строки, вызывающей исключение, не был проблемой, я разместил ее в комментарии выше. Строка была Beech-Nut Stage 2;Mixed Vegetables;4 oz;5.67;6047, и я не вижу, чем она отличается от предыдущих строк Beech-Nut Stage 2;Pears;4 oz;2.95;5925 Beech-Nut Stage 2;Pears & Pineapple;4 oz;7.27;6031 Beech-Nut Stage 2;Pears & Raspberries;4 oz;8.83;5731 Beech-Nut Stage 2;Butternut Squash;4 oz;1.39;5932 Beech-Nut Stage 2;Country Garden Vegetables;4 oz;10.04;6046. Последний токен заканчивается тем, что Vegata уже несколько раз без проблем разделил строковые овощи.
Вы нашли плохую линию, но знаете ли вы, почему она плохая? Очевидно, он не содержит 5 токенов. Вы знаете, сколько жетонов split() вернулось за эту строку? Кроме того, какая строка исходного кода, которую вы разместили, является строкой 59?
2 Beech-Nut Stage 2 и Mixed Vegeta. Строка 59 была бы System.out.println(tokens[2]);
Это не похоже на код Java. Я имел в виду строку 59 вашего java-кода. Если вы используете IDE, например Затмение, в трассировке стека должна быть ссылка, которая приведет вас прямо к этой строке в вашем коде.
Выложил первую половину ответа перед строкой кода. Этот бит был из файла. Трудно превзойти ввод мышечной памяти в комментариях на этом сайте.
удалив строку Beech-Nut Stage 2;Mixed Vegetables;4 oz;5.67;6047, и код заработал без ошибок. Я просто не могу понять, чем отличается эта строка
Именно то, что я подозревал. ArrayIndexOutOfBoundsException потому что tokens содержит только два элемента. Вам нужно тщательно изучить эту линию. Возможно, распечатайте символы, используя метод toCharArray() класса java.lang.String.
Когда я вырезал и вставил строку обратно в файл после ее удаления, эта строка теперь работает правильно. Я предполагаю, что профессор включил какой-то специальный символ в качестве пограничного случая, который был удален при копировании.
tokens = line.split(";");: это не кажется запрограммированным...