내일배움캠프/TIL

[Java] 클래스를 사용하여 기본연산 계산기 만들기 트러블슈팅

cork-7 2025. 1. 8. 23:11

<조건>

  1. 사칙연산 수행 후 결과값을 반환하고 결과를 출력하는 Calculator클래스 생성
  2. 이전 클래스없이 만든 App클래스에 Calculator클래스가 활용되게 코드 수정 (연산 수행은 Calculator에서 진행)
  3. App클래스에서 Calculator클래스를 직접적으로 접근못하게 수정

<목표>

- App클래스에서 연산부분 제외 while문 유지 및  기록저장/삭제 문구 추가

package com.example.calculator2;

import java.util.ArrayList;

public class Calculator {
    // 결과 값 저장을 위한 배열 생성 및
    private ArrayList<String> record = new ArrayList<>();

    // 생성자 (위에서 이미 초기화를 해 기본생성자로 작성해도 이상없음 안적어도 실행은 됨)
    public Calculator() {
    }

    // 계산 기록을 반환
    public ArrayList<String> getRecord() {
        return new ArrayList<>(record);
    }

    // 계산 기록에서 맨 처음 기록을 삭제
    public void removeRecord(int index) {
        if (index >= 0 && index < record.size()) {
            this.record.remove(index);
        }
    }

    // 계산 식
    public int calculate(int fristNum, char operator, int secondNum) {
        int result = 1;

        switch (operator) {
            case ('+'):
                result = fristNum + secondNum;
                break;
            case ('-'):
                result = fristNum - secondNum;
                break;
            case ('*'):
                result = fristNum * secondNum;
                break;
            case ('/'):
                if (secondNum == 0) {
                    System.out.println("나눗셈의 분모에는 0이 들어갈 수 없습니다.\n");
                    System.out.println("다시 입력해주세요");
                    return 0;
                }
                result = fristNum / secondNum;
                break;
            default:
                System.out.println("유효하지 않은 연산자입니다. 다시 입력해주세요.");
                return 0;
        }
        // 계산이 끝나면 출력
        System.out.println("계산 결과 =" + result);

        // 계산 결과를 배열에 추가
        String calculate = fristNum + " " + operator + " " + secondNum + "= " + result;
        record.add(calculate);
        return result;
    }
}

Calculator

package com.example.calculator2;

import java.util.Scanner;

public class App {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 객체 생성
        Calculator calculator = new Calculator();

        boolean start = true;

        // 반목문 시작
        while (start) {
            System.out.println("숫자를 입력해주세요");
            int fristNum = sc.nextInt();

            System.out.println("연산자를 입력해주세요 [ + , - , * , / ]");
            char operator = sc.next().charAt(0);

            System.out.println("숫자를 입력해주세요");
            int secondNum = sc.nextInt();

            // 계산 시작
            // 나눗셈 분모에 0이 들거가거나 연산자를 잘못입력하면 처음으로 이동
            int result = calculator.calculate(fristNum, operator, secondNum);
            if (result == 0) {
                continue;
            }

            // 계산 종료 후 추가 계산이나 기록, 삭제
            System.out.println("더 계산하시겠습니까? (yes 입력 시 추가 계산,exit 입력 시 종료, record 입력 시 계산기록 출력, remove 입력 시 계산기록 삭제)");
            String outText = sc.next();

            if (outText.equals("exit")) {
                System.out.println("계산을 종료합니다.");
                break;
            } else if (outText.equals("record")) {
                System.out.println("저장된 계산 기록:");
                for (String record : calculator.getRecord()) {
                    System.out.println(record);
                }
                // 맨 처음 계산기록을 삭제
            } else if (outText.equals("remove")) {
                calculator.removeRecord(0);
                System.out.println("기록 삭제 후:");
                for (String record : calculator.getRecord()) {
                    System.out.println(record);
                }
            } else if (outText.equals("yes")) {
                continue;
            }
        }
    }
}

<오류>

연산값이 0이 나오면 자동반복됨 [ex) 45-45 = 0]

<문제파악> 

Calculator에서 분모에 0이 들어가거나 연산자를 잘못입력하면 다시 반복문이 실행되게 할려고 return 0;을 주고

App에서 return값이 오면 다시 진행하게 작성했더니 연산값이 0이 나와도 반복되기 시작

<해결>

예외를 처리하여 특정상황에 다시 반복하게 코드 작성

package test;

import java.util.Scanner;

public class App {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 객체 생성
        Calculator calculator = new Calculator();

        boolean start = true;

        // 반목문 시작
        while (start) {
            System.out.println("숫자를 입력해주세요");
            int fristNum = sc.nextInt();

            System.out.println("연산자를 입력해주세요 [ + , - , * , / ]");
            char operator = sc.next().charAt(0);

            System.out.println("숫자를 입력해주세요");
            int secondNum = sc.nextInt();

            // 계산 시작
            // 나눗셈 분모에 0이 들거가거나 연산자를 잘못입력하면 처음으로 이동
            int result = calculator.calculate(fristNum, operator, secondNum);
            if (result == 0) {
                continue;
            }
            // 계산 종료 후 추가 계산이나 기록, 삭제
            System.out.println("더 계산하시겠습니까? (yes 입력 시 추가 계산,exit 입력 시 종료, record 입력 시 계산기록 출력, remove 입력 시 계산기록 삭제)");
            String outText = sc.next();

            if (outText.equals("exit")) {
                System.out.println("계산을 종료합니다.");
                break;
            } else if (outText.equals("record")) {
                System.out.println("저장된 계산 기록:");
                for (String record : calculator.getRecord()) {
                    System.out.println(record);
                }
                // 맨 처음 계산기록을 삭제
            } else if (outText.equals("remove")) {
                calculator.getRemoveRecord(0);
                System.out.println("기록 삭제 후:");
                for (String record : calculator.getRecord()) {
                    System.out.println(record);
                }
            } else if (outText.equals("yes")) {
                continue;
            }

        }
    }
}

 

package test;

import java.util.ArrayList;

public class Calculator {
    // 결과 값 저장을 위한 배열 생성 및
    private final ArrayList<String> record = new ArrayList<>();

    // 생성자 (위에서 이미 초기화를 해 기본생성자로 작성해도 이상없음 안적어도 실행은 됨)
    public Calculator() {
    }

    // 계산 기록을 반환
    public ArrayList<String> getRecord() {
        return new ArrayList<>(record);
    }

    // 계산 기록에서 맨 처음 기록을 삭제
    public void getRemoveRecord(int index) {
        if (index >= 0 && index < record.size()) {
            this.record.remove(index);
        }
    }

    // 계산 식
    public int calculate(int firstNum, char operator, int secondNum) {
        int result = 0;
        try {
            switch (operator) {
                case ('+'):
                    result = firstNum + secondNum;
                    break;
                case ('-'):
                    result = firstNum - secondNum;
                    break;
                case ('*'):
                    result = firstNum * secondNum;
                    break;
                case ('/'):
                    if (secondNum == 0) {
                        throw new ArithmeticException("나눗셈의 분모에는 0이 들어갈 수 없습니다. 다시입력해주세요");
                    }
                    result = firstNum / secondNum;
                    break;
                default:
                    throw new IllegalArgumentException("유효하지 않은 연산자입니다. 다시 입력해주세요.");
            }
        } catch (ArithmeticException | IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
        // 계산이 끝나면 출력
        System.out.println("계산 결과 =" + result);

        // 계산 결과를 배열에 추가
        String calculate = firstNum + " " + operator + " " + secondNum + " = " + result;
        record.add(calculate);
        return result;
    }
}

- try~catch문으로 예외 발생시 문장을 출력하고 반복문을 나가는 코드를 적지 않아서 다시 반복문을 진행하게 작성

- ArithmeticException : 나눗셈에서 분모에 0이 들어가면 발생하는 예외

- IllegalArgumentException : 전달된 메소드가 유호하지 않으면 발생하는 예외

- 예외 발생시 문자 출력 후 코드 반복