Я пытаюсь сделать программу кодирования/декодирования, и я сталкиваюсь здесь со всеми видами исключений!
проблемы, которые появляются, вызванные несколькими/одними сканерами:
InputMismatchException | NumberFormatException (ПОПЫТКА 2)
NoSuchElementException (ПОПЫТКА 3)
Прежде чем продолжить, я хотел бы сказать, что это не дубликат, и я просмотрел множество проблем такого рода в StackOverFlow, и ни одна из них мне не помогла. Похожие проблемы, которые я рассматривал: link1 link2
Обратите внимание, что желаемые конечные результаты аналогичны результатам первой попытки, но с более чистой обработкой исключений и закрытыми сканерами.
ПЕРВАЯ ПОПЫТКА
Теперь эта программа дает мне желаемые результаты, но это плохое программирование иметь два сканера, и один из них (сканер метода ввода) никогда не закрывается:
public static void main(String[] args) { Scanner sc=new Scanner (System.in); int choice = 0; do { System.out.println("This program to encode or decode a byte array " + "\n (o_O) Choices are: " + "\n 1: Press 1 to enter the encode mode" + "\n 2: Press 2 to enter the decode mode" + "\n 3: Press 3 to Exit!"); try { //it has to be parseInt because if you used sc.nextInt() the program will go nuts even with try catch. choice=Integer.parseInt(sc.next()); //choice=sc.nextInt(); /*Question: why when i use this with the existing try catch i the program work for ever but when i use Integer.parseInt(sc.nextLine()) * the program would normally ask for another value? */ } catch (InputMismatchException | NumberFormatException e) { System.out.println("invalid type or format!"); } catch (NoSuchElementException e) { System.out.println("no such"); //break; if i uncomment this the programm will work For Ever } switch(choice){ case 1 : System.out.println("entering the encode mode!"); countAndEncode( input() ); break; case 2 : countAndDecode( input() ); break; case 3 : System.out.println("exiting..."); break; default : System.out.println("please enter a valid option and valid format!"); } } while (choice!=3); sc.close(); } public static byte [] input() { //arrayList because we dont know the size of the array its like StringBuilder //ArrayList<Byte> inArray = new ArrayList<Byte>(); //according to StackOverflow using ArrayList to store bytes is inefficient Scanner inScanner=new Scanner (System.in); ByteArrayOutputStream inArray= new ByteArrayOutputStream(); System.out.println("enter a sequence of ints please! "); System.out.println("non-int will terminate the input!"); while (inScanner.hasNext()) { byte i; try { i = inScanner.nextByte(); inArray.write(i); } catch (InputMismatchException e) { System.out.println("input terminated!"); break; } } //System.out.println(Arrays.toString(inArray.toByteArray())); //inScanner.close(); return inArray.toByteArray(); }
ВЫВОД ПЕРВОЙ ПОПЫТКИ:
This is a program to encode or decode bytes based on RLE ALgorithm
(o_O) Choices are:
1: Press 1 to enter the encode mode
2: Press 2 to enter the decode mode
3: Press 3 to Exit!
1
entering the encode mode!
enter a sequence of bytes please!
non-int will terminate the input!
1
1
3
e
input terminated!
[1, 1, 3]
the encoded list is [-1, 1, 2, 3]
This is a program to encode or decode bytes based on RLE ALgorithm
(o_O) Choices are:
1: Press 1 to enter the encode mode
2: Press 2 to enter the decode mode
3: Press 3 to Exit!
At it goes forever without errors.
ВТОРАЯ ПОПЫТКА
так что я сделал после того, как один из вас, ребята, предложил взглянуть на эту проблему ссылка вот такая:
Теперь я не закрывал сканер ввода и передал методу ввода сканер в качестве параметра:
public static void main(String[] args) {
Scanner sc=new Scanner (System.in);
int choice = 0;
do {
System.out.println("This is a program to encode or decode bytes based on RLE ALgorithm" +
"\n (o_O) Choices are: " +
"\n 1: Press 1 to enter the encode mode" +
"\n 2: Press 2 to enter the decode mode" +
"\n 3: Press 3 to Exit!");
try {
//it has to be parseInt because if you used sc.nextInt() the program will go nuts even with try catch.
choice=Integer.parseInt(sc.next());
//choice=sc.nextInt();
/*Question: why when i use this with the existing try catch i the program work for ever but when i use Integer.parseInt(sc.nextLine())
* the program would normally ask for another value?
*/
} catch (InputMismatchException | NumberFormatException e) {
System.out.println("invalid type or format!");
} catch (NoSuchElementException e) {
System.out.println("no such");//TODO SOLVE IT PLEASE ITS DRIVING ME CRAZYYYYYYYYYYY!!!!!!!
break;
}
switch(choice){
case 1 :
System.out.println("entering the encode mode!");
countAndEncode( input(sc) );
break;
case 2 :
//countAndDecode( input(sc) );
break;
case 3 :
System.out.println("exiting...");
break;
default :
System.out.println("please enter a valid option and valid format!");
}
} while (choice!=3);
sc.close();
}
/**
* with this method user will be able to give the desired sequence of bytes.
* @return a byte array to be encoded.
*/
public static byte [] input(Scanner inScanner) {
//arrayList because we dont know the size of the array its like StringBuilder
//ArrayList<Byte> inArray = new ArrayList<Byte>();
//according to StackOverflow using ArrayList to store bytes is inefficient
//Scanner inScanner=new Scanner (System.in);
ByteArrayOutputStream inArray= new ByteArrayOutputStream();
System.out.println("enter a sequence of bytes please! ");
System.out.println("non-int will terminate the input!");
while (inScanner.hasNext()) {//TODO THIS MIGHT BE THE REASON FOR THE above "SUCH"
byte i;
try {
i = inScanner.nextByte();
inArray.write(i);
} catch (InputMismatchException e) {
System.out.println("input terminated!");
break;
}
}
System.out.println(Arrays.toString(inArray.toByteArray()));
//inScanner.close(); dont close it because it cant be re-opened
return inArray.toByteArray();
}
Это вообще не дает мне желаемых результатов:
После выбора одного для кодирования и получения закодированных байтов я навсегда застряну в режиме кодирования, и будет активировано предложение
InputMismatchException | NumberFormatException
, поэтому я не могу выбрать новый ввод!Это программа для кодирования или декодирования байтов на основе алгоритма RLE (o_O). Возможные варианты: 1: Нажмите 1, чтобы войти в режим кодирования 2: Нажмите 2, чтобы войти в режим декодирования 3: Нажмите 3, чтобы выйти! 1 вход в режим кодирования! введите последовательность байтов, пожалуйста! non-int прервет ввод! 1 e вход прекращен! 1 закодированный список 1 Это программа для кодирования или декодирования байтов на основе алгоритма RLE ALgorithm (o_O). Варианты: 1: нажмите 1, чтобы войти в режим кодирования 2: нажмите 2, чтобы войти режим декодирования 3: Нажмите 3 для выхода! неверный тип или формат! вход в режим кодирования! введите последовательность байтов, пожалуйста! non-int прервет ввод!
ПРИМЕЧАНИЯ:
- 1. комментирование
sc.close()
в main вызвало ту же ошибку, что и выше.. - 2. что перемещение сканера над основным и объявление его глобальной статической переменной сделало то же самое, что и приведенный выше результат.
ТРЕТЬЯ ПОПЫТКА
теперь я оставил оба сканера закрытыми, и это активировало NoSuchElementException
в главном. Взгляните:
public static void main(String[] args) {
Scanner sc=new Scanner (System.in);
int choice = 0;
do {
System.out.println("This is a program to encode or decode bytes based on RLE ALgorithm" +
"\n (o_O) Choices are: " +
"\n 1: Press 1 to enter the encode mode" +
"\n 2: Press 2 to enter the decode mode" +
"\n 3: Press 3 to Exit!");
try {
//it has to be parseInt because if you used sc.nextInt() the program will go nuts even with try catch.
choice=Integer.parseInt(sc.next());
//choice=sc.nextInt();
/*Question: why when i use this with the existing try catch i the program work for ever but when i use Integer.parseInt(sc.nextLine())
* the program would normally ask for another value?
*/
} catch (InputMismatchException | NumberFormatException e) {
System.out.println("invalid type or format!");
} catch (NoSuchElementException e) {
System.out.println("no such");//TODO SOLVE IT PLEASE ITS DRIVING ME CRAZYYYYYYYYYYY!!!!!!!
break;
}
switch(choice){
case 1 :
System.out.println("entering the encode mode!");
countAndEncode( input() );
break;
case 2 :
//countAndDecode( input() );
break;
case 3 :
System.out.println("exiting...");
break;
default :
System.out.println("please enter a valid option and valid format!");
}
} while (choice!=3);
sc.close();
}
/**
* with this method user will be able to give the desired sequence of bytes.
* @return a byte array to be encoded.
* @throws IOException
*/
public static byte [] input() {
//arrayList because we dont know the size of the array its like StringBuilder
//ArrayList<Byte> inArray = new ArrayList<Byte>();
//according to StackOverflow using ArrayList to store bytes is inefficient
Scanner inScanner=new Scanner (System.in);
ByteArrayOutputStream inArray= new ByteArrayOutputStream();
System.out.println("enter a sequence of bytes please! ");
System.out.println("non-int will terminate the input!");
while (inScanner.hasNext()) {//TODO THIS MIGHT BE THE REASON FOR THE above "SUCH"
byte i;
try {
i = inScanner.nextByte();
inArray.write(i);
} catch (InputMismatchException e) {
System.out.println("input terminated!");
break;
}
}
System.out.println(Arrays.toString(inArray.toByteArray()));
inScanner.close();
return inArray.toByteArray();
}
в этой попытке я, по крайней мере, мог бы знать, что заставляет NoSuchElementException
подпрыгивать, и я думаю, что это потому, что закрытие одного сканера закроет входной поток для всего кода (поправьте меня, если я ошибаюсь!)
ВЫВОД ДЛЯ ТРЕТЬЕЙ ПОПЫТКИ:
This is a program to encode or decode bytes based on RLE ALgorithm
(o_O) Choices are:
1: Press 1 to enter the encode mode
2: Press 2 to enter the decode mode
3: Press 3 to Exit!
1
entering the encode mode!
enter a sequence of bytes please!
non-int will terminate the input!
-1
-1
e
input terminated!
[-1, -1]
the encoded list is [-1, -1, -1, -1]
This is a program to encode or decode bytes based on RLE ALgorithm
(o_O) Choices are:
1: Press 1 to enter the encode mode
2: Press 2 to enter the decode mode
3: Press 3 to Exit!
no such
РЕШЕНИЕ ДЛЯ ОБСУЖДЕНИЯ @Villat
В первую очередь большое спасибо тебе, чувак, за помощь и потраченное время и силы. Теперь у меня есть небольшой вопрос относительно этих строк:
if(sc.hasNextInt()) choice=sc.nextInt();
else {
sc.next();
continue;
}
error = false;
- Итак, позвольте мне посмотреть, правильно ли я понял, эти строки играют роль меры предосторожности, и, пожалуйста, поправьте меня, если я ошибаюсь!, чтобы исключение не появлялось правильно.
Поэтому было бы недостаточно написать следующее, исключая блоки try-catch
, потому что NoSuchElementException
не имеет шансов появиться, а InputMismatchException
обрабатывается и предотвращается блоком else:
while (error){
if(sc.hasNextInt()) choice=sc.nextInt();
else {
sc.next();
continue;
}
error = false;
}
Просто для целей обучения, если бы я хотел обработать эту ошибку блоком try-catch
, вы бы считали ее чистой и невосприимчивой к исключениям, если бы я написал это так: (отбросив NumberFormatException
)
-так Демонстрация Handle variant
вашего ответа будет такой, верно?
while (error){
try {
choice=sc.nextInt();
error = false;
} catch (InputMismatchException /*| NumberFormatException*/ e) {
error = false;
//System.out.println("invalid type or format!");
sc.next();
continue;
}
}
InputMismatchException
, но это не проблема, это просто завершит ввод в методе ввода, и моя основная проблема заключается в третья попытка при закрытии входного потока,NoSuchElementException
catch каким-то образом активируется в основном? - person StudentAccount4   schedule 11.10.2019