gpt4 book ai didi

java - 是否可以将 try 与资源和输入流一起使用?

转载 作者:行者123 更新时间:2023-12-02 01:19:33 25 4
gpt4 key购买 nike

当使用资源实现 try 时,我通过 try 语句的 () 内的 Scanner sc = new Scanner(System.in) 创建一个 Scanner 对象。在 try block 中,我提示用户输入一个数值,通过 sc.nextLine() 读取它并利用 parseDouble 将其转换为方法。如果最初输入的值无效,我会利用 do-while 循环重新提示用户输入值。

但是,如果用户输入无效值,输入流将关闭,NumberFormatException 会被捕获,但在 do-while 循环的第二次迭代期间,会抛出“未找到行”NoSuchElementException,并且此后由于“流关闭”java.io.IOException而无限期。有没有办法在利用资源尝试时规避这个问题?

public static void main(String[] args) {

int x = 1;

do {
try (Scanner sc = new Scanner(System.in)) {
System.out.print("Enter a numeric value: ");
String input1 = sc.nextLine();
Double d1;
d1 = Double.parseDouble(input1);
System.out.print("Enter a numeric value: ");
String input2 = sc.nextLine();
Double d2;
d2 = Double.parseDouble(input2);
System.out.print("Choose an operation (+ - * /): ");
String input3 = sc.nextLine();
//sc.close();

switch (input3) {
case "+":
Double result = d1 + d2;
System.out.println("The answer is " + result);
break;
case "-":
Double result1 = d1 - d2;
System.out.println("The answer is " + result1);
break;
case "*":
Double result2 = d1 * d2;
System.out.println("The answer is " + result2);
break;
case "/":
Double result3 = d1 / d2;
System.out.println("The answer is " + result3);
break;
default:
System.out.println("Unrecognized Operation!");
break;
}
x++;
}
catch (NumberFormatException e){
System.out.println("Number formatting exception "+e.getMessage());
System.out.println("Enter a proper value");
}
catch (Exception e1){
System.out.println("Arbitrary error encountered"+e1.getMessage());
}
}
while(x==1);

}

最佳答案

正如其他人在评论中已经说过的,您不应该将 try-with-resource 与您自己没有打开的资源一起使用,特别是不应该与 System.in 一起使用,这永远不应该由应用程序关闭。

除此之外,您应该更喜欢事先测试条件,而不是捕获异常。此外,尽量避免代码重复,您最终会得到一个更简单的解决方案:

public static void main(String[] args) {
Scanner sc = new Scanner(System.in).useDelimiter("\\R");
System.out.print("Enter first numeric value: ");
double d1 = getDouble(sc);
System.out.print("Enter second numeric value: ");
double d2 = getDouble(sc);
System.out.print("Choose an operation (+ - * /): ");
while(!sc.hasNext("[-+*/]")) {
System.out.println(sc.next()+" is not a valid operation");
}
String operation = sc.next();

double result;
switch (operation) {
case "+": result = d1 + d2; break;
case "-": result = d1 - d2; break;
case "*": result = d1 * d2; break;
case "/": result = d1 / d2; break;
default:
throw new AssertionError("should not happen due to pretest");
}
System.out.println(d1+operation+d2);
System.out.println("The answer is " + result);
}
private static double getDouble(Scanner sc) {
while(!sc.hasNextDouble()) {
System.out.println(sc.next()+" is not a number");
}
return sc.nextDouble();
}

此解决方案使用 hasNextDouble() 询问扫描器下一个 token 是否具有 double 格式,只有在确认的情况下,应用程序才会通过 nextDouble() 获取它。否则,它使用 next() 获取无效 token ,该 token 同时服务于报告并将其从未处理的输入中删除。同样,hasNext("[-+*/]") 检查输入是否与支持的四个运算符之一匹配。

由于编译器不知道现在只能出现四个有效输入之一,因此我们必须在 switchdefault 情况下添加一个 throwing 语句,否则编译器会说 result 可能尚未初始化。我们可以将 result 初始化为默认值,但如果程序流程未按预期工作,最好有一个强信号,而不是将默认值打印为错误结果。

Scanner 使用可配置的分隔符来决定 token 的构成,因此该解决方案使用 useDelimiter("\\R") 使用换行符作为分隔符,以考虑每行一个标记,就像您的原始代码一样。所以Pattern class有关语法的完整说明。

关于java - 是否可以将 try 与资源和输入流一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57969142/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com