我正在尝试编写编码/解码程序,但是我遇到了各种异常!
出现问题的原因是由多个/单个扫描器引起的:
InputMismatchException | NumberFormatException(尝试2)
NoSuchElementException(尝试3)
在继续之前,我想说明这不是重复的问题,我已经在StackOverFlow上查看了多个类似的问题,但没有真正帮助我解决。
请注意,期望的最终结果类似于第一次尝试的结果,但具有更好的清晰的异常处理和关闭的扫描器。
第一次尝试
Now this program gives me the desired results but its a bad programming to have two scanners and one of them ( input method scanner ) is never closed:
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
进入编码模式!
请输入一系列字节!
非int类型将终止输入!
1
e
输入终止!
1
编码后的列表为1
这是一个基于RLE算法对字节进行编码或解码的程序(o_O) 选项如下:
1. 按1进入编码模式
2. 按2进入解码模式
3. 按3退出!
类型或格式无效!
进入编码模式!
请输入一系列字节!
非int类型将终止输入!注意事项:
- 1.在主函数中注释掉
sc.close()
与上述错误完全相同。
- 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
没有机会出现,而且通过else块处理并防止了InputMismatchException
:
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;
}
}