김코딩

계산기 Lv.1 본문

TIL

계산기 Lv.1

김코딩딩 2025. 4. 16. 20:39

오늘은 자바를 공부하면서 만들어본 간단한 계산기 예제를 소개하려고 합니다.
이 예제는 총 3단계(Lv1~Lv3)로 나누어져 있으며, 자바 언어에 조금씩 익숙해지는 데 도움이 되었습니다.

이번에는 Lv 1 단계의 요구사항과 구현 흐름을 정리해보았습니다.


Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기

  • 양의 정수(0 포함)를 입력받기
    • Scanner를 사용하여 양의 정수 2개(0 포함)를 전달 받을 수 있습니다.
    • 양의 정수는 각각 하나씩 전달 받습니다.
    • 양의 정수는 적합한 타입으로 선언한 변수에 저장합니다.
  • 사칙연산 기호(➕,➖,✖️,➗)를 입력받기
    • Scanner를 사용하여 사칙연산 기호를 전달 받을 수 있습니다.
    • 사칙연산 기호를 적합한 타입으로 선언한 변수에 저장합니다. (charAt(0))
  • 위에서 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력하기
    • 키워드 : if switch
    • 사칙연산 기호에 맞는 연산자를 사용하여 연산을 진행합니다.
    • 입력받은 연산 기호를 구분하기 위해 제어문을 사용합니다. (예를 들면 if, switch)
    • 연산 오류가 발생할 경우 해당 오류에 대한 내용을 정제하여 출력합니다.
      • ex) “나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.“
  • 반복문을 사용하되, 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지 무한으로 계산을 진행할 수 있도록 소스 코드를 수정하기
    • 키워드 : 무한으로 반복, 수정하기 (처음부터 무한 반복하는 것이 아니라, 위 스텝별로 진행하며 수정)
    • 반복문을 사용합니다. (예를 들어, for, while…)

요구사항 세부 정리

 

  • 1. 양의 정수 입력
    • Scanner를 사용하여 두 개의 양의 정수를 입력받습니다.
    • 정수가 아닌 값이 입력되면 InputMismatchException 예외를 처리합니다.
    2. 사칙연산 기호 입력
    • 문자열을 입력받고 charAt(0)을 이용해 문자로 추출합니다.
    • 사용 가능한 연산자: +, -, *, /
    3. 계산 수행
    • if 문을 이용해 연산자에 따라 분기 처리
    • / 연산 시 분모가 0인지 검사
    4. 무한 반복 및 종료
    • while 문으로 전체 계산을 감싸고, "exit"이 입력되면 종료

리팩토링 전 코드

package lv1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class App {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        while (true) {
            int num1 = 0;
            while (true) {
                System.out.print("첫 번째 숫자를 입력하세요: ");
                try {
                    num1 = sc.nextInt();
                    if (num1 < 0) {
                        System.out.println("0 이상의 정수만 입력 가능합니다.");
                        continue;
                    }
                    break;
                } catch (InputMismatchException e) {
                    System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
                    sc.nextLine();
                }
            }

            int num2 = 0;
            while (true) {
                System.out.print("두 번째 숫자를 입력하세요: ");
                try {
                    num2 = sc.nextInt();
                    if (num2 < 0) {
                        System.out.println("0 이상의 정수만 입력 가능합니다.");
                        continue;
                    }
                    break;
                } catch (InputMismatchException e) {
                    System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
                    sc.nextLine();
                }
            }
            sc.nextLine();

            System.out.print("사칙연산 기호를 입력하세요(예: +,-,*,/) : ");
            char operator = sc.nextLine().charAt(0);


            double result = 0.0;
            if (operator == '+') {
                result = num1 + num2;
            } else if (operator == '-') {
                result = num1 - num2;
            } else if (operator == '*') {
                result = num1 * num2;
            } else if (operator == '/') {
                if (num2 == 0) {
                    System.out.println("나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.");
                    continue;
                } else {
                    result = (double) num1 / num2;
                }
            } else {
                System.out.println("올바른 연산자를 입력해주세요.");
            }
            System.out.println("결과: " + result);

            System.out.print("더 계산하시겠습니까? (exit 입력 시 종료): ");
            String order = sc.nextLine();
            if (order.equals("exit")) {
                System.out.println("계산기를 종료합니다. 안녕히 가세요");
                break;
            }
        }
    }

 

구현 설명

  1. num1과 num2에 숫자를 받습니다. (숫자 이외의 문자가 들어오면 InputMismatchException이 터지기 때문에 숫자만 받을 수 있도록 예외처리를 해놓았습니다)
  2. operator 문자에 연산기호를 입력합니다.
  3. 연산 결과는 나눗셈을 한다는 가정하에 소숫점이 나올 수 있기 때문에 result 변수를 int형 말고 double형으로 선언해주었습니다.
  4. 이제 if문을 사용하여 각 연산자에 맞는 연산을 진행하도록 합니다. 하지만 나눗셈 연산이 들어왔을 때에는 분모가 0일때를 고려하여 조건을 다시 넣어주었습니다. 이때 분모에 0이 들어올 시 continue문을 사용하여 다시 while문이 돌아가게 만들었습니다.
  5. 연산이 종료되면 결과가 나옵니다
  6. 만약에 연산 종료 후 사용자가 exit을 입력하게 되면 break를 사용하여 while문을 빠져나와 프로그램이 종료되게 됩니다.

리팩토링 후 코드

package lv1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class App {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        while (true) {
            // 첫 번째 숫자 입력 : 정수를 입력 받기 위한 스캐너 변수와 메시지를 매개변수로 받습니다.
            int num1 = inputNumber(sc, "첫 번째 숫자를 입력하세요: ");

            // 두 번째 숫자 입력
            int num2 = inputNumber(sc, "두 번째 숫자를 입d력하세요: ");

            // 연산자 입력
            char operator = getOperator(sc);

            // 연산자에 맞는 연산 수행
            double result = 0.0;
            if (operator == '+') {
                result = add(num1, num2);
            } else if (operator == '-') {
                result = subtract(num1, num2);
            } else if (operator == '*') {
                result = multiply(num1, num2);
            } else if (operator == '/') {
                if (num2 == 0) {
                    System.out.println("나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.");
                    continue;
                } else {
                    result = (double) num1 / num2;
                }
            } else {
                System.out.println("올바른 연산자를 입력해주세요.");
                continue;
            }

            // 연산 결과 출력
            System.out.println("결과: " + result);

            // if 문을 도입하여 exit 입력 시 프로그램 종료
            System.out.print("더 계산하시겠습니까? (exit 입력 시 종료): ");
            String order = sc.nextLine();
            if (order.equals("exit")) {
                System.out.println("계산기를 종료합니다. 안녕히 가세요");
                break;
            }
        }
    }

    private static double multiply(int num1, int num2) {
        double result;
        result = num1 * num2;
        return result;
    }

    private static double subtract(int num1, int num2) {
        double result;
        result = num1 - num2;
        return result;
    }

    private static double add(int num1, int num2) {
        double result;
        result = num1 + num2;
        return result;
    }

    private static char getOperator(Scanner sc) {
        System.out.print("사칙연산 기호를 입력하세요(예: +,-,*,/) : ");
        return sc.nextLine().charAt(0);
    }

    private static int inputNumber(Scanner sc, String message) {
        while (true) {
            System.out.print(message);
            try {
                int num = sc.nextInt();
                if (num < 0) {
                    System.out.println("0 이상의 정수만 입력 가능합니다.");
                    continue;
                }
                sc.nextLine();
                return num;
            } catch (InputMismatchException e) {
                System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
                sc.nextLine();
            }
        }
    }
}

구현 설명

1. inputNumber() 메서드로 숫자 입력 로직 분리

// 첫 번째 숫자 입력 : 정수를 입력 받기 위한 스캐너 변수와 메시지를 매개변수로 받습니다.
int num1 = inputNumber(sc, "첫 번째 숫자를 입력하세요: ");

// 두 번째 숫자 입력
int num2 = inputNumber(sc, "두 번째 숫자를 입력하세요: ");
private static int inputNumber(Scanner sc, String message) {
    while (true) {
        System.out.print(message);
        try {
            int num = sc.nextInt();
            if (num < 0) {
                System.out.println("0 이상의 정수만 입력 가능합니다.");
                continue;
            }
            sc.nextLine();
            return num;
        } catch (InputMismatchException e) {
            System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
            sc.nextLine();
        }
    }
}
  • 반복되는 정수 입력 로직을 하나의 메서드로 묶어 중복을 제거했습니다.
  • 메시지를 매개변수로 받아서 첫 번째/두 번째 입력에 모두 사용할 수 있습니다.
  • 음수 입력 시 안내 메시지를 출력하고 다시 입력을 유도합니다.
  • 숫자가 아닌 문자가 들어올 경우 InputMismatchException을 처리합니다.

2. getOperator() 메서드로 연산자 입력 분리

char operator = getOperator(sc);
private static char getOperator(Scanner sc) {
    System.out.print("사칙연산 기호를 입력하세요(예: +,-,*,/) : ");
    return sc.nextLine().charAt(0);
}
  • 연산자 입력은 문자열로 받아 charAt(0)을 통해 문자로 변환합니다.

3. 사칙연산 별로 add(), subtract(), multiply() 메서드로 분리

if (operator == '+') {
    result = add(num1, num2);
} else if (operator == '-') {
    result = subtract(num1, num2);
} else if (operator == '*') {
    result = multiply(num1, num2);
}
private static double add(int num1, int num2) {
    double result;
    result = num1 + num2;
    return result;
}
private static double subtract(int num1, int num2) {
    double result;
    result = num1 - num2;
    return result;
}
private static double multiply(int num1, int num2) {
    double result;
    result = num1 * num2;
    return result;
}
  • 각각의 연산을 별도의 메서드로 나누어 코드의 의도를 더 명확히 표현했습니다.
  • 나중에 클래스 단위로 리팩토링하거나 테스트하기에도 수월해집니다.

다음 단계에서는 이 로직을 기반으로 Calculator 클래스를 만들어 기능을 분리하는 Lv 2 단계로 넘어갈 예정입니다.

https://github.com/SexyDoGyun/Calculator

 

GitHub - SexyDoGyun/Calculator

Contribute to SexyDoGyun/Calculator development by creating an account on GitHub.

github.com

 

'TIL' 카테고리의 다른 글

계산기 Lv.3  (0) 2025.04.22
이놈의 Enum, 그거 어떻게 쓰는건데?  (0) 2025.04.22
계산기 Lv.2  (0) 2025.04.17
객체지향  (1) 2025.04.15
KPT 회고  (0) 2025.04.11