#java #string #exception #indexoutofboundsexception
#java #строка #исключение #исключение indexoutofboundsexception
Вопрос:
Я изучаю Java, и у нас есть проект по созданию программы, переводящей текст в ASCII и обратно.
Мой основной метод до сих пор
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
char decisionOne;
System.out.println("Are we making a new message or decrypting an old one?");
decisionOne = s.nextLine().charAt(0);
switch(decisionOne) {
case 'd':
decrypt();
System.exit(0);
break;
case 'D':
decrypt();
System.exit(0);
break;
case 'E':
encrypt();
System.exit(0);
break;
case 'e':
encrypt();
System.exit(0);
break;
}
while (!(decisionOne == 'd') amp;amp; !(decisionOne == 'D') amp;amp; !(decisionOne == 'e') amp;amp; !(decisionOne == 'E')) {
System.out.println("Hey! Choose one of them.");
decisionOne = s.nextLine().charAt(0);
switch(decisionOne) {
case 'd':
decrypt();
System.exit(0);
break;
case 'D':
decrypt();
System.exit(0);
break;
case 'E':
encrypt();
System.exit(0);
break;
case 'e':
encrypt();
System.exit(0);
break;
}
}
}
и мой метод шифрования в ASCII
Scanner s = new Scanner(System.in);
System.out.println("What is your message?");
String message = s.nextLine();
char m;
int length = message.length();
int tracker = 0;
int ascii;
while (length >= 0 ) {
m = message.charAt(tracker);
length--;
ascii = (int)m;
System.out.print(ascii " ");
tracker ;
}
}
Я просмотрел другие вопросы, но ни один из них, похоже, не отвечает на то, что здесь происходит. При запуске я получаю правильный вывод, поэтому, если я ввел
11
Я бы получил
49 49 Исключение в потоке «main» java.lang.StringIndexOutOfBoundsException: строковый индекс вне диапазона: 2
Что я могу сделать, чтобы исправить это?
Комментарии:
1. Вы узнали об отладчике Java? Или модульные тесты?
2. Метод string#length() возвращает буквальное числовое значение. Если вы собираетесь использовать его значение для методов, для которых требуется значение индекса, такое как String#charAt(), тогда используйте:
int length = message.length() - 1;
Ответ №1:
Измените свой код в методе encrypt с while(length >= 0)
на while(length - 1 >= 0)
. Также закройте объект scanner после его использования, поскольку это приведет к утечке памяти.
Метод length() возвращает длину строки, например String message = "Hello"; length = message.length();
, длина будет равна 5. Но при использовании его в цикле while вы должны использовать message .length() — 1, потому что в Java индексация начинается с 0, а не с 1.
Я переработал ваш метод encypt и метод main, а также я чувствую, что нет необходимости использовать операторы switch. Замените их операторами if else, чтобы уменьшить избыточный код.
Если вы считаете это решение полезным, пожалуйста, поддержите решение, спасибо.
public static void encrypt() {
Scanner s = new Scanner(System.in);
System.out.println("What is your message?");
String message = s.nextLine();
char m;
int length = message.length();
int tracker = 0;
int ascii;
while (length - 1 >= 0 ) {
m = message.charAt(tracker);
length--;
ascii = (int)m;
System.out.print(ascii " ");
tracker ;
}
s.close();
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
char decisionOne;
System.out.println("Are we making a new message [e (or) E] or decrypting an old one [d (or) D] ?");
decisionOne = s.nextLine().charAt(0);
if (decisionOne == 'd' || decisionOne == 'D') {
decrypt();
System.exit(0);
}
else if (decisionOne == 'e' || decisionOne == 'E') {
encrypt();
System.exit(0);
}
while (!(decisionOne == 'd') amp;amp; !(decisionOne == 'D') amp;amp; !(decisionOne == 'e') amp;amp; !(decisionOne == 'E')) {
System.out.println("Hey! Choose one of them.");
decisionOne = s.nextLine().charAt(0);
if (decisionOne == 'd' || decisionOne == 'D') {
decrypt();
System.exit(0);
}
else if (decisionOne == 'e' || decisionOne == 'E') {
encrypt();
System.exit(0);
}
}
s.close();
}
Комментарии:
1. Входной поток будет закрыт после вызова encrypt , поэтому не будет необходимости снова закрывать его из основного метода. Почему бы просто не передать сканер в качестве параметра?
2. Да. Это сделало бы это, я не думал об этом. Я только что отладил ошибки, которые были запрошены. В любом случае этот код может быть переработан дальше.
3. Какие могут быть другие способы реорганизовать это?
Ответ №2:
Я вставил это в ваш метод шифрования и..
m = message.charAt(tracker);
System.out.print(length " ");
length--;
ascii = (int)m;
System.out.print(ascii " ");
tracker ;
System.out.print(length " " tracker " ");
результат, который я получил, это thisss…
2 49 1 1 1 49 0 2
вы видите ваш tracker=2 в последнем, который не привязан к вашей строке сообщения, поэтому вы получаете исключение, либо вы можете обработать исключение, либо улучшить свой код… личный опыт — используйте цикл for, если вы новичок, это даст вам больше ясности в том, как работает код
Ответ №3:
Вы хотите while (length > 0)
или while (tracker < length)
Или вы можете просто сделать for (Character m: message.toCharArray())
и отказаться от метода length, tracker и charAt