【问题标题】:How to Repeat `try` Block for Specific Cases?如何针对特定情况重复“try”块?
【发布时间】:2016-07-20 09:55:59
【问题描述】:

我这里有一个程序,它接受一个数值(存储为BigDecimal)和存储为String 的货币(美元或人民币)。在用户 dimo414 的帮助下,我能够解释空白输入和非数字输入,同时还允许用户重试直到读取到有效输入。

代码如下:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    System.out.print("Enter the amount of money and specify" 
        + " currency (USD or CNY): ");
    Boolean invalidInput;  // breaks out of do-while loop after successful outcome

    do {
        invalidInput = false;
        try {
            String line = input.nextLine();
            Scanner lineScan = new Scanner(line);
            BigDecimal moneyInput = lineScan.nextBigDecimal();
            String currency = lineScan.next();

            if (currency.equals("USD")) {
                // convert USD to CNY
            } else if (currency.equals("CNY")) {
                // convert CNY to USD
            } else {
                /*
                reprompt user for currency,
                but retain the value of moneyInput;
                repeat process until valid currency
                 */
            }
        } catch (NoSuchElementException | IllegalStateException e) {
            // deals with errors:
            // non-numeric moneyInput or blank input
        }
    } while (invalidInput);
}

现在我在处理 moneyInput 有效但 currency 无效时遇到问题,例如100.00 abc。在这种情况下,我想提示用户重新输入currency 的值同时保留 money 的值。

我尝试在提示 currency 的部分周围使用类似的 do-while 循环,然后继续进入 if-else 块,如下所示:

do {
    String currency = lineScan.next();

    if (currency.equals("USD")) {
        // convert USD to CNY
    } else if (currency.equals("CNY")) {
        // convert CNY to USD
    } else {
        invalidInput = true;
        System.out.print("Please enter a valid currency: ");
        // since invalidInput == true,
        // jump back up to the top of the do block
        // reprompt for currency 
    }
} while (invalidInput);

但是这个解决方案是无效的,因为它会显示来自外部 catch 块的异常错误消息,所以我实际上必须在 try-catch 块内的 try-catch 块内实现一个 do-while 循环,很快就变得一团糟。

我还尝试在 main 之外定义一个名为 readCurrency 的新函数,我可以在 else 块中调用它,但我遇到了变量范围的问题。我仍然是 Java 初学者,所以我不知道如何正确定义函数并将必要的信息传递给它。

还有哪些其他方法可以循环回到该 try 块的顶部并允许用户仅重新输入货币

非常感谢您阅读并提供反馈。

【问题讨论】:

  • 你不能分两步要求输入吗: - 插入金额 //处理金额 - 插入货币 //处理它 每个“交易”将是不同的方法,这可以要求重新输入输入或任何需要的内容
  • 如果用户第一次插入100.00 abc,程序会问用户什么?
  • @nickzoum 显示来自catch 块的错误消息,然后是我暂时放置在else 块中的打印消息。然后用户可以重新输入。这是一个截图以防万一(imgur.com/a/Z2PRc)。请注意,对于重新输入,程序需要moneycurrency 才能继续。
  • @SCouto 由于处理 moneyInput 的部分在 do-while 循环内,moneyInputdo 块内有一个范围,所以我无法单独处理 currency
  • 我会写一个答案

标签: java loops try-catch do-while


【解决方案1】:

您将输入验证与处理混合在一起。一次做一件事,首先验证,然后处理。使用助手进行一点代码模块化,这变得非常简单。

String amountString;
String currencyString;
do {
 System.out.println("Please insert a valid amount and currency");
 String line = input.readLine();
 String[] values = line.split("\\s"); //split on the space
 amountString = values[0];
 currencyString = values[1];

}
while (!isValidAmount(amountString));
while (!isValidCurrencyString(currencyString) {
  System.out.println("Amount accepted but unsupported currency. Please input only the correct currency now");
  currencyString = input.nextLine();
}

现在你需要的是 helpers 方法:

  • boolean isValidAmount(String amountString)
  • boolean isValidCurrency(String currencyString)

一旦你拥有它们并完成了验证,你就可以实际插入处理逻辑了:

BigDecimal amount = BigDecimal.parse(amountString); //this may be the wrong name of the parse function, don't remember but something like that;
switch(currencyString) {
  case "USD": //...
}

你能自己写辅助方法吗?他们应该很容易:)

【讨论】:

  • +1 表示乐于助人而又不付出太多。你的回答帮助我在思考事情的顺序上朝着正确的方向前进,谢谢:)
【解决方案2】:

我在评论中的建议是将金额的检索和货币的检索分开,这样您就可以开发不同的解决方案,并为每个解决方案开发不同的循环。我做了一个简单的例子。希望对您有所帮助:

主要方法

 public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

    BigDecimal moneyInput = getMoneyInput(input);
    String currencyInput = getCurrency(input);

    System.out.println(moneyInput.toString() + " " + currencyInput);
}

获取货币功能

public static String getCurrency(Scanner input) {
    System.out.print("Enter the currency: ");

    String currency = null;
    boolean invalidInput = true;
    try {

        do {
            String line = input.nextLine();
            if ("USD".equals(line) || "CNY".equals(line)) {
                invalidInput = false;
                currency = line;
            } else {
                System.out.print("Invalid currency, enter it again please");
            }
        } while (invalidInput);


    } catch (Exception e) {
        System.out.println(e.getMessage());
        System.out.print("Invalid currency, enter it again please");

    }
    return currency;


}

获取金额函数

public static BigDecimal getMoneyInput(Scanner input) {
    System.out.print("Enter the amount of money without the currency: ");

    BigDecimal moneyInput = BigDecimal.ZERO;
    boolean invalidInput = true;
    try {

        do {
            String line = input.nextLine();
            moneyInput = new BigDecimal(line);
            invalidInput = false;

        } while (invalidInput);


    } catch (Exception e) {
        System.out.println(e.getMessage());
        System.out.print("Invalid input, enter it again please");

    }
    return moneyInput;

}

【讨论】:

  • 嗨,我真的很喜欢你的解决方案,因为它向我介绍了定义多个函数并将它们一起使用的正确方法,但我想维护的一个主要功能是允许用户输入两个钱和货币一次性
【解决方案3】:

好的,因此需要进行一些重组才能使代码正常工作。

input 对象用于从控制台获取值。

currency 值是在循环 (do-while) 中获取的,其中循环条件是货币不应该等于“美元”或“人民币”。这消除了对invalidInput 循环变量的需要。

    public static void main(String[] args) {
           try {
            Scanner input = new Scanner(System.in);
            System.out.print("Enter the amount of money and specify" 
                + " currency (USD or CNY): ");

            //Boolean invalidInput;  // Not required
            //String line = input.nextLine();
            //Scanner lineScan = new Scanner(line);

            String currency =null;

            BigDecimal moneyInput = input.nextBigDecimal();

            do{     
                if(currency!=null){
                  System.out.print("Please enter a valid currency: ");
                }
                currency = input.next();
            }while(!currency.equals("USD")&&!currency.equals("CNY"));

            if (currency.equals("USD")) {
                // convert USD to CNY
            } else if (currency.equals("CNY")) {
                // convert CNY to USD
            }
            } catch (NoSuchElementException | IllegalStateException e) {
                // deals with errors:
                // non-numeric moneyInput or blank input
            }
    }

【讨论】:

  • @AisforAmbition 你能试试我的代码吗?我看不出它是如何引发任何错误的……因为我们正在默默地处理它……
  • 我的错误,我已经删除了我之前的评论。感谢您的帮助和反馈:)
  • 虽然,我想从原始代码中保留的一件事是让程序每次都重复提示用户,直到在输入空白的情况下输入有效输入,有点像你用“请输入有效的货币”做了。这是 do-while 循环中 invalidInput 布尔值的初衷。我现在想看看我是否可以重新实现它,因为你给了我一个很好的起点。
【解决方案4】:

给你:

public void main(String[] args){
    Scanner input = new Scanner(System.in);
    String message = "Enter the amount of money and specify currency (USD or CNY)";
    System.out.println(message);
    boolean invalidInput = true;
    BigDecimal moneyInput = null;
    String currency = null;
    do{
        try{
            String line = input.nextLine();
            Scanner lineScan = new Scanner(line);
            BigDecimal temp = lineScan.nextBigDecimal();
            if(temp == null){
                if(moneyInput == null){
                    System.out.println(message);
                    continue;
                }
            }else{
                    moneyInput = temp;
            }
            String tempCurrency = lineScan.next().toUpperCase();
            if(!temp.isValid()){
                if(currency == null){
                    System.out.println("Reenter currency:");
                    continue;
                }
            }else{
                currency = tempCurrency;
            }
            if (currency.equals("USD")) {
                // convert USD to CNY
            } else {
                // convert CNY to USD
            }
            invalidInput = false;
        }catch(Exception e){
            System.out.println(message);
            moneyInput = null;
        }
    }while(invalidInput);
}

你还需要添加这个方法:

public boolean isValid(String currency){
    return currency.equals("USD") || currency.equals("CNY");
}

这将一直持续到两个值都有效,并且不会强制用户重新输入另一个 BigDecimal(如果已提供有效值),但它将允许用户在每次货币时更改 BigDecimal无效。

【讨论】:

    猜你喜欢
    • 2020-05-31
    • 2013-09-29
    • 1970-01-01
    • 2017-07-12
    • 2011-07-04
    • 2013-02-20
    • 1970-01-01
    • 2011-08-18
    • 2016-10-13
    相关资源
    最近更新 更多