如何针对具体案例重复“尝试”阻止?

时间:2016-07-20 09:55:59

标签: java loops try-catch do-while

我这里有一个程序接受一个数值(存储为BigDecimal)和货币(USD或CNY)存储为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块内部实现do-while循环-catch block,这很快就搞得很乱。

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

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

非常感谢阅读和提供反馈。

4 个答案:

答案 0 :(得分:1)

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

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

currency值在循环(do-while)中获取,其中循环条件是该货币不应等于' USD'或者' CNY'。这消除了对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
            }
    }

答案 1 :(得分: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();
}

现在您需要的是帮助方法:

  • 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": //...
}

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

答案 2 :(得分:1)

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

主要方法

 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);
}

GetCurency功能

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;


}

GetAmount功能

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 :(得分:0)

你走了:

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每次货币无效。