Repetition loop in Java

Asked

Viewed 93 times

0

Hello I am new in Java language, I would like to know how I could implement a repetition loop every time an Inputmismatchexception type exception was capture, in this case return to the beginning of the program for the user to enter new valid data.

Example of a possible error:

Enter Account data

Number: "abcde"

Unexpected error

So in this case I would like the program to return to the beginning for the user to enter with valid data.

Follow the source code:

public class Program {
public static void main(String[] args) {
    Locale.setDefault(Locale.US);

    try (Scanner sc = new Scanner(System.in)) {
        System.out.println("Enter account data");
        System.out.print("Number: ");
        int number = sc.nextInt();
        System.out.print("Holder: ");
        sc.nextLine();
        String holder = sc.nextLine();
        System.out.print("Initial balance: ");
        double initialBalance = sc.nextDouble();
        System.out.print("Withdraw limite: ");
        double withdrawLimite = sc.nextDouble();

        Account account = new Account(number, holder, initialBalance, withdrawLimite);

        System.out.println();

        System.out.print("Do you like to deposit a amount? (y/n) ");
        char r = sc.next().charAt(0);

        if (r == 'y') {
            System.out.print("Enter amount for deposit: ");
            double amountDeposit = sc.nextDouble();
            account.deposit(amountDeposit);
            System.out.print("New balance: $ " + String.format("%.2f", account.getBalance()));
            System.out.println();
        }

        System.out.println();

        System.out.print("Enter amount for withdraw: ");
        double amountWithdraw = sc.nextDouble();
        account.withdraw(amountWithdraw);
        System.out.println("New balance: $ " + String.format("%.2f", account.getBalance()));

        System.out.println();

        System.out.println("Account Data:");
        System.out.println(account);
    }
    catch (WithdrawException e) {
        System.out.println("Withdraw error: " + e.getMessage());
    }
    catch (InputMismatchException e) {
        System.out.println("unexpected error");
    }
}

}

The program dealt with a simple example of data entry of a supposed bank account (number, username, initial balance, withdrawal limit), later is asked if the user would like to deposit an amount, and then is made the realization of a withdrawal.

1 answer

2


First: the use of Try-with-Resources is interesting in many cases because it already automatically closes the resources. But in the specific case of System.in, no need to close it (read more about it here and here).


On the problem of repeating/returning to the beginning, at first it would be enough to do something like:

Scanner sc = new Scanner(System.in);
while (true) {
    try {
        // ler os dados

        break; // se chegou aqui é porque não deu erro, então interrompe o *loop*
    } catch(InputMismatchException e) {
        // erro
        sc.nextLine();
    }
}

I mean, if something goes wrong, you’re in catch and the while continue running. Only if you arrive at the end of the block try, after everything has been read, then the loop is interrupted.

But this is not a very smart approach. Imagine that you have read almost all the data, and only in the last one is it wrong. In this case, it will go back to the beginning and the user will have to type everything again (including the first data that was correct).

Instead, it would not be better for him to type back only the data that gave error?


So I would create separate methods to read whole numbers and double. Something like that:

static int lerInt(Scanner sc, String mensagem) {
    while (true) {
        System.out.print(mensagem);
        try {
            return Integer.parseInt(sc.nextLine());
        } catch (NumberFormatException e) {
            System.out.println("Não foi digitado um número inteiro válido, tente novamente");
        }
    }
}

static double lerDouble(Scanner sc, String mensagem) {
    while (true) {
        System.out.print(mensagem);
        try {
            return Double.parseDouble(sc.nextLine());
        } catch (NumberFormatException e) {
            System.out.println("Não foi digitado um número válido, tente novamente");
        }
    }
}

Note that instead of using nextInt and nextDouble, i use nextLine to read everything that was typed (until the user gives ENTER) and try to convert to number (thereby eliminating the need to keep calling nextLine soon after, as you did at some points of the code). While the information entered is not a number, you are asked to type again.

Thus, you only ask the user to type again the data that gave error, not needing to repeat the others. So the reading code would no longer need to capture the InputMismatchException:

Scanner sc = new Scanner(System.in);
System.out.println("Enter account data");
int number = lerInt(sc, "Number: ");
System.out.print("Holder: ");
String holder = sc.nextLine();
System.out.print("Initial balance: ");
double initialBalance = lerDouble(sc, "Initial balance: ");
double withdrawLimite = lerDouble(sc, "Withdraw limit:");

Account account = new Account(number, holder, initialBalance, withdrawLimite);

System.out.println();
System.out.print("Do you like to deposit a amount? (y/n) ");
if ("y".equals(sc.nextLine())) {
    double amountDeposit = lerDouble(sc, "Enter amount for deposit:");
    account.deposit(amountDeposit);
    System.out.printf("New balance: $ %.2f\n", account.getBalance());
}

System.out.println();

double amountWithdraw = lerDouble(sc, "Enter amount for withdraw: ");
account.withdraw(amountWithdraw);
System.out.printf("New balance: $ %.2f\n\n", account.getBalance());

System.out.println("Account Data:\n" + account);

Of course, if you want you can still capture the WithdrawException.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.