Прежде чем задать этот вопрос, я потратил около получаса в Google, но, поскольку я не нашел решения, я подумал, что мне, возможно, стоит спросить здесь. Итак, в основном я использую Java Reader для чтения текстового файла и преобразования каждой строки информации в объект, который я назвал Nation (конечно, с конструктором), и создания массива из всех этих объектов. Проблема в том, что одна строка в моем текстовом файле состоит из 75 символов. Но я получаю сообщение об ошибке, что длина всего 68! Итак, вот часть кода, в которой я читаю информацию из файла:
static int lireRemplir (String nomFichier, Nation[] nations)
throws IOException
{
boolean existeFichier = true;
int n =0;
FileReader fr = null;
try {
fr = new FileReader(nomFichier);
}
catch (java.io.FileNotFoundException erreur) {
System.out.println("Probléme avec l'ouverture du fichier " + nomFichier);
existeFichier = false;
}
if (existeFichier) {
BufferedReader entree = new BufferedReader(fr);
boolean finFichier = false;
while (!finFichier) {
String uneLigne = entree.readLine();
if (uneLigne == null) {
finFichier=true;
}
else {
nations[n] = new Nation(uneLigne.charAt(0),uneLigne.substring(55,63),
uneLigne.substring(64,74),uneLigne.substring(1,15),uneLigne.substring(36,54));
n++;
}
}
entree.close();
}
return n;
}
Я получаю следующую ошибку:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 64, end 74, length 68
Поскольку я здесь новичок, я попытался опубликовать изображение своего текста, но не смог, поэтому я просто попробую вручную написать пример:
2ETATS-UNIS WASHINGTON 9629047 291289535
4ЧИНЕ ПЕКИН 9596960 1273111290
3JAPON KYOTO 377835 12761000
Между словами много места, это как массив!
Если я изменю 74 на 68, я получаю результат, когда пытаюсь распечатать свой массив, но информация отсутствует.
Вот мой конструктор:
public Nation(char codeContinent, String superficie, String population, String nom, String capitale) {
this.codeContinent = codeContinent;
this.superficie = superficie;
this.population = population;
this.nom = nom;
this.capitale = capitale;
}
Надеюсь, вы могли бы мне помочь с этим! Если вам нужно узнать больше о моем коде, дайте мне знать! Большое спасибо.
Как уже упоминалось, просто добавьте System.out.println(uneLigne.length()) в качестве первого оператора блока else.
Не заслуживает доверия. java.lang.String.substring() достаточно хорошо протестирован за последние 22 года. Очевидно, вы ошибаетесь насчет длины строки. Если вы не согласны, предоставьте убедительные доказательства.
Где-то в вашем файле есть строка всего из 68 символов. Посчитай еще раз. И убедитесь, что при подсчете вы используете кодировку символов по умолчанию для вашей платформы.
Я попытался распечатать длину каждой строки, и выяснилось, что есть только одна строка с 68 символами, все остальные - 71,72 или 73
Да. Точно. Вы получите ошибку в строке из 68 символов.
Вы не предоставили примеры данных, из которых извлекаете подстроку. Обязательно ли использовать подстроку? Может быть, можно извлечь нужные данные, используя комбинацию contains() и indexOf() или даже regExp, независимо от длины строки?
Данные, которые я извлекаю, выглядят так: 2ETATS-UNIS WASHINGTON 9629047 291289535 это массив, поэтому между словами много места, есть ли у вас какие-либо другие предложения, я буквально новичок в java
Пожалуйста, не размещайте эту очень важную информацию в комментариях, где ее могут легко пропустить другие читатели. Вставьте это в вопрос и добавьте несколько примеров, чтобы читатели поняли структуру данных.
Пожалуйста, опубликуйте дословный пример кода, который вы хотите обработать. Вы написали "между словами много пробела", сколько пробелов? Как заполнено пространство? Добавьте примеры в виде блоков кода, чтобы не терять пробелы при форматировании.




Чтобы избежать исключений времени выполнения, вам нужно быть осторожным с вашим кодом. В случаях, когда вы имеете дело с индексами String или массива, убедитесь, что длина String больше или равна максимальному индексу, который вы используете. Приложите код, который генерирует исключение, в:
if (uneLigne.length() > 74) {
nations[n] = new Nation(uneLigne.charAt(0),uneLigne.substring(55,63),
uneLigne.substring(64,74),uneLigne.substring(1,15),uneLigne.substring(36,54));
} else {
//your logic to handle the line with less than 74 characters
}
Это гарантирует, что ваш код не сломается, даже если какая-либо строка меньше ожидаемых символов.
______________________________________________________________________________
Другой подход
Добавление комментария в качестве ответа:
Другой способ - использовать метод расколоть() класса String или StringTokenizer для получения массива / токенов, если строка разделена пробелом или каким-либо другим символом. При этом вам не нужно разбивать строку с помощью метода substring (), когда вам нужно беспокоиться о длине и возможном времени выполнения.
Проверьте приведенный ниже фрагмент кода, используя метод split (), для каждой строки, которую вы читаете из файла, вам, вероятно, придется делать это следующим образом:
Nation nation = null;
String uneLigne = "2ETATS-UNIS WASHINGTON 9629047 291289535";
String[] strArray = uneLigne.split(" ");
if (strArray.length > 3) {
nation = new Nation(getContinentCodeFromFirstElement(strArray[0]), strArray[1],
strArray[2], strArray[3], strArray[4]);
}
//getContinentCodeFromFirstElement(strArray[0]) is your private method to pick the code from your first token/element.
Я понимаю ! Но разве нет другого решения, кроме как обрабатывать его по длине?
@Django: См. Мой комментарий к самому вопросу: вы должны предоставить примеры данных, которые вы используете. Может быть, есть способ сделать то, что вы хотите, без использования жестко запрограммированных чисел. Это решение также не собирает информацию в строках с length < 74 ... может быть, это не нужно?
Другой способ - использовать метод split () класса String или StringTokenizer для получения токенов, если строка разделена пробелом или каким-либо другим символом. При этом вам не нужно разбивать строку с помощью метода substring ().
Я только что выложил пример своих данных!
Для каждой строки вам, вероятно, придется сделать так: String str= "2ETATS-UNIS WASHINGTON 9629047 291289535"; String[] strArray = str.split(" "); if (strArray.length > 3) { Nation nation = new Nation(getCodeFromFirstElement(strArray[0]), strArray[1], strArray[2], strArray[3], strArray[4]) }
Хорошо ! Большое спасибо, Хамена, за ваш конкретный пример, мне пришлось написать дополнительную строку кода, но теперь он работает! Поскольку никто не голосует против этого вопроса, я просто буду придерживаться вашего ответа!
Спасибо вам тоже JavaYouth!
@Django: Я не ответил на ваш вопрос, но JavaYouth ответила. Если он вставит код из своего комментария в свой ответ, я с радостью проголосую за него.
Добавлен код из комментария для ответа в качестве альтернативного подхода
Самый простой способ решить вашу проблему - заменить 74 на une Ligne.length. Вот новый код.
nations[n] = new Nation(uneLigne.charAt(0),uneLigne.substring(55,63),
uneLigne.substring(64,uneLigne.length),uneLigne.substring(1,15),uneLigne.substring(36,54));
Это будет работать, если ваша строка гарантированно содержит> 64 символа, в противном случае вы получите то же исключение.
Из того, что он опубликовал, я понял, что текстовый файл похож на массив, поэтому всегда есть номер строки, с которой начинается столбец, и это 64 для его случая.
Он сказал, что «между словами много пробела», но не уточнил, сколько места. Таким образом, могут быть примеры, содержащие менее 64 символов, которые не будут работать с этим решением.
Ахмед прав, он всегда начинается с определенного номера строки, поэтому он решил мою проблему без особых изменений в моем коде! спасибо за ваши ответы всем вам
The problem is that a single line on my text file goes to 75 characters- возможно, это не так для всех строк вашего файла. Достаточно легко проверить, есть ли более короткие строки. Просто выведите длину каждой строки.