> Java > java지도 시간 > 본문

연습 - 터미널을 사용하여 은행 계좌 시뮬레이션

PHPz
풀어 주다: 2024-08-12 22:43:49
원래의
309명이 탐색했습니다.

이론에서 조금 벗어나기 위해 부트캠프의 다음 단계는 연습입니다(프로젝트 챌린지라고 함). 지금까지 다룬 내용을 통합하기 위해 실무적인 부분도 포함하면 재미있겠다는 생각이 들었습니다.

요청한 것은 지점 번호, 계좌 번호, 고객 이름 및 균형. 이 데이터는 터미널에서 가져와야 하며 마지막에는 계정이 성공적으로 생성되었음을 알리고 어떤 데이터가 입력되었는지 보여주는 메시지가 표시되어야 합니다. 원래 설명은 여기에서 볼 수 있습니다.

아주 간단한 것 같습니다. 하지만 제가 받는 어떤 일이든 제가 정말 좋아하는 한 가지는 일을 매우 짧은 단계로 나누어 제가 따라야 할 명확한 경로를 확보하는 것입니다. 머리 속으로 흐름을 그려가면서 질문한 내용이 맞는지 이해할 수 있고, 안 된다고 생각되면 빠르게 방향을 바꿀 수 있기 때문에 이렇게 하는 것이기도 합니다.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

따라서 따라야 할 단계는 다음과 같습니다.

    단말기에서 받은 데이터와 계정 생성 방법을 "수납"하는 클래스를 만듭니다.
  1. 사용자에게 데이터를 요청하고 단말기에 입력된 정보를 읽어 변수에 저장합니다.
  2. 변수를 읽을 수 있는 문자열로 정리하여 사용자에게 확인 메시지를 표시합니다.
딱히 복잡한 내용은 아닌 것 같습니다. 1단계부터 시작하면 다음과 같습니다.

TerminalAccount.java

public class TerminalAccount { // eu sei, sou muito criativo
    private int branch;
    private String account;
    private String clientName;
    private double balance;

    public void createAccount(){
        // aqui a mágica acontece
    }
}
로그인 후 복사
접근 한정자는 지금까지 과정에서 깊이 다루지 않았지만 은행 시스템에서는 지점, 계좌, 보유자 및 잔액 데이터가 잘 보호되어야 하고 클래스만 보호되어야 한다고 생각하여 모든 필드를 비공개로 유지하기로 결정했습니다. 자체적으로 액세스할 수 있어야 합니다.

또한 createAccount 메소드는 아무것도 반환하지 않고 콘솔에 메시지만 표시하므로 반환이 무효화됩니다.

이 방법은 Java에 대해 나를 짜증나게 하는 일 중 일부가 시작되는 곳입니다. 이를 위해 사용되는 Scanner 클래스에는 사용자가 입력하는 모든 유형의 정보를 캡처하는 일반적인 메소드 대신
각 기본 유형에 대한 특정 메소드가 있습니다. 즉, 문자열의 경우 Scanner.nextLine(), 숫자의 경우 Scanner.nextInt(), 부울의 경우 Scanner.nextBoolean...

Exercício - Simulando Uma Conta Bancária Através Do Terminal

비교해 보면 C#에는 항상 문자열을 반환하고 그 유형이 변경되는 표준 입력 방법이 있습니다.


String input = Console.ReadLine();
int.TryParse(input, out number)
Console.WriteLine(number) //completamente válido
로그인 후 복사
조금 더 써야 하나요? 그는 그랬다. 그러나 최소한 모든 메소드의 구문을 기억할 필요는 없습니다. 하나만 기억하고 다음에 원하는 유형으로 변환하면 됩니다. 훨씬 더 직관적입니다.

하지만 계속해서 이 문제를 해결하려면 아직 갈 길이 멀습니다. 다음 단계는 사용자에게 등록을 위해 고객 데이터를 입력하도록 요청하는 것입니다.

TerminalAccount.java

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  
        System.out.print("Por favor, insira o número da agência: ");  
        this.branch = sc.nextInt();  

        System.out.print("Por favor, insira o número da conta: ");  
        this.account = sc.nextLine();  

        System.out.print("Por favor, insira o nome do cliente: ");  
        this.clientName = sc.nextLine();  

        System.out.print("Por favor, insira o saldo inicial: ");  
        this.balance = sc.nextDouble();  

        System.out.println("Olá " + this.clientName + ", obrigado por criar uma conta em nosso banco. sua agência é " + this.branch + ", conta " + this.account + " e seu saldo " + this.balance + " já está disponível para saque.");  
    }  
}
로그인 후 복사
글쎄, 모든 게 괜찮은 것 같군요. 기본 메소드에서 이 클래스를 인스턴스화하고 무슨 일이 일어나는지 살펴보겠습니다.

Main.java

public class Main {  
    public static void main(String[] args) {  
        TerminalAccount account = new TerminalAccount();  
        account.createAccount();  
    }  
}
로그인 후 복사

Exercício - Simulando Uma Conta Bancária Através Do Terminal

옥스? 계좌번호 입력은 무시되고 알고리즘이 이미 고객 이름을 요구한 이유는 무엇입니까?

Scanner 클래스에 대한 문서를 읽으면 중지할 위치를 알기 위해 특정 유형의 문자를 구분 기호로 사용하여 입력을 토큰으로 나누는 것으로 설명됩니다. .next() 및 .hasNext() 메서드(및 .nextInt() 및 .hasNextInt()와 같은 변형)의 경우 구분 기호는 공백, 탭 및 줄 바꿈과 같은 전역 공백(s+)입니다. .

메서드가 수행하는 작업은 구분 기호 앞에 있는 토큰을 가져와 지정된 유형으로 변환하고 해당 값을 반환하는 것입니다. 나머지는 입력 버퍼에 남아있습니다.

알았어, 지금까지는 괜찮았어. 문제는 문자열
을 캡처하는 데 사용되는 .nextLine() 메서드가 줄 바꿈 문자(n)를 버리는 대신 소비한다는 것입니다. 그러다가 버리는 다른 것을 따라가면 남은 것을 읽고 즉시 작업을 종료하고 다음 코드 줄로 이동합니다.

혼란스럽게 들리는데, 그렇습니다. 이 흐름이 얼마나 광기적인지 이해하는 데 도움이 되도록 다이어그램을 만들었습니다.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Tá, e como consertamos essa lambança? Simples: adicionando um novo Scanner.nextLine() logo depois do .nextInt() para "limpar" o que sobrou. É bonito? Não, mas resolve.
Dá pra mudar o delimitador para aceitar a quebra de linha (\n ) em vez de um whitespace comum (\s+), mas isso poderia quebrar a forma com que as informações são quebradas em tokens, então é melhor deixar pra lá.

TerminalAccount.java

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  
        System.out.print("Por favor, insira o número da agência: ");  
        this.branch = sc.nextInt();  
        sc.nextLine();

        //...
    } 
}
로그인 후 복사

Mais feio que bater na mãe.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Beleza, funcionou. Poderíamos dizer que o exercício está completo, mas vamos por um segundo imaginar que o usuário, sem querer, digitou uma letra na hora de colocar o número da agência:

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Eita lasqueira.

Isso acontece porque, como já sabemos, a tipagem do Java é estática e o Scanner está esperando um número mas quando colocamos uma letra junto com um número, essa cadeia se torna uma String. O input que estava esperando um int recebeu uma String e ficou confuso tal qual uma criança que recebe meias de presente de natal.
Exercício - Simulando Uma Conta Bancária Através Do Terminal

Para remediar essa situação, podemos criar um loop simples, que informe para o usuário que a informação que ele inseriu está incorreta de acordo com as especificações do sistema e pedir que ele insira os dados novamente (de maneira correta, dessa vez). Como não sabemos quantas tentativas o usuário vai levar para inserir os dados corretamente, um while parece adequado.

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  

        boolean isBranchNumberInputCorrect = false;  
        do {  
            try {  
                System.out.print("Por favor, insira o número da agência: ");  
                this.branch = sc.nextInt();  
                sc.nextLine();  
                isBranchNumberInputCorrect = true;  
            } catch (InputMismatchException e) {  
                System.out.println("Por favor, insira apenas números inteiros para o número da agência."); 
                sc.nextLine(); 
            }  
        } while (!isBranchNumberInputCorrect);

        //...
    }
}
로그인 후 복사

Aqui criamos uma variável de controle chamada IsBranchNumberInputCorrect (porque, novamente, sou muito criativo quando se trata de nomes), inicializada em false. Em seguida, começamos o bloco do, uma vez que queremos que o código faça uma ação antes de verificar se o dado inserido é valido ou não e jogamos nosso input lá pra dentro.
Caso dê tudo certo, o dado inserido será armazenado no campo branch, qualquer caractere sobrando será consumido pelo Scanner.nextLine() e a nossa variável de controle será atualizada para true. Aí a condição do while vai checar se isBranchNumberInputCorrect é false. Se for, reinicia o loop no caso de sucesso, o laço é encerrado.

Agora, caso o usuário insira algo não esperado (como uma String), o método Scanner.nextInt() vai emitir um evento de erro InputMismatchException, que será capturado pelo nosso bloco catch. Uma vez lá dentro, o código vai exibir uma mensagem de erro alertando que o tipo de dado está errado e consumido qualquer caractere que tenha ficado pra trás.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

A gente pode fazer a mesma coisa com o input de saldo, para garantir que o valor inserido sempre será numérico e não permitir que a aplicação quebre caso seja inserido algo como 12,56f:

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in); 

        //...

        boolean isBalanceInputCorrect = false;  
        do {  
            try {  
                System.out.print("Por favor, insira o saldo inicial: ");  
                this.balance = sc.nextDouble();  
                sc.nextLine();  
                isBalanceInputCorrect = true;  
            } catch (InputMismatchException e) {  
                System.out.println("Por favor, insira apenas valores decimais.");  
                sc.nextLine();  
            }  
        } while (!isBalanceInputCorrect);  

        //...
    }  
}
로그인 후 복사

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Poderíamos parar por aqui e dar esse exercício como encerrado, mas ainda tem um bug que requer um pouco de atenção. O que aconteceria se, em vez de delimitarmos nosso saldo com uma vírgula (,) usássemos um ponto (por exemplo, 10.56)?

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Isso acontece devido ao locale, a adaptação do input à cultura do local. Aqui no Brasil, o decimal é delimitado pela vírgula, então o método não entende que essa separação com ponto é válida.
A documentação da classe Scanner nos mostra que é possível alterar a cultura para uma que atenda ou um ou outro padrão, mas não os dois ao mesmo tempo. Também é possível alterar especificamente o delimitador, para um símbolo ou para outro, mas não os dois ao mesmo tempo.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Um dos métodos para solucionar esse problema não é muito elegante, mas resolve: em vez de capturar o dado diretamente como double, vamos usar o método Scanner.nextLine() para pegar o input como uma String, trocar os pontos por vírgula e tentar trocar o tipo para double.

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  

        //...
        boolean isBalanceInputCorrect = false;  
        do {  
            try {  
                System.out.print("Por favor, insira o saldo inicial: ");  
                String balanceString = sc.nextLine().replace(",", ".");  
                this.balance = Double.parseDouble(balanceString);  
                isBalanceInputCorrect = true;  
            } catch (NumberFormatException e) {  
                System.out.println("Por favor, insira apenas valores decimais.");  
            }  
        } while (!isBalanceInputCorrect);  

        //...

    }  
}
로그인 후 복사

Além da alteração do método de captura do dado, tivemos mais algumas modificações: retiramos as chamadas para o método Scanner.nextLine() que serviam apenas para consumir os caracteres remanescentes, porque nosso input já faz isso pra gente. Além disso, o tipo do erro mudou: agora não se trata de um erro de incompatibilidade de tipo (InputMismatchException), mas sim um de erro no formato do número (NumberFormatException).
Com essas alterações feitas, bora ver se tudo deu certo:

Exercício - Simulando Uma Conta Bancária Através Do Terminal
Exercício - Simulando Uma Conta Bancária Através Do Terminal

Exercício - Simulando Uma Conta Bancária Através Do Terminal
Deu tudo certo! Com isso, conseguimos dizer que o exercício está concluído (finalmente)!
O repositório desse exercício está disponível aqui caso tenha interesse de ver.

E é isso. Até o próximo módulo!

위 내용은 연습 - 터미널을 사용하여 은행 계좌 시뮬레이션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!