계산기 트러블슈팅

‍박태우·2024년 9월 9일

nbc_spring

목록 보기
12/28

트러블슈팅

1) 배경
Java 를 이용한 계산기를 하나의 Main 클래스 안에 모두 구현하려는 Lv1 계산기를 만드는 중이었으며, 이때 올바르지 않은 입력 값이 나온 경우에 대한 예외처리를 구현하고 테스트 중이었다.

2) 발단

=> 테스트 시 위와 같이 한번만 입력을 일부러 틀리게 했는데 위와 같이 무한루프를 돌면서 지속적으로 처리가 발생하고 있다는 것을 발견하게 되었다.
(첫 번째 숫자가 계속 정수가 아닌 다른 것으로 입력되고 있는 듯 하였다.)

3) 전개
해당 예외를 처리하는 코드로 이동해서 봤지만 로직이나 코드에 아무런 문제가 없다는 것을 확인 해서 아래와 같이 처리를 해봤지만 해당 코드는 계산기 조건에 부합하지 않았다.

 catch(InputMismatchException e){
                System.out.println("양의 정수가 아닌 이상한 값이 들어옴");
                break;
            }

위 결과는 예외처리 라기보다는 프로그램 강제 종료 느낌이었다.


4) 위기
문제의 조건을 만족하면서 적절하게 반복되도록 break 문을 제거해도 여전히 문제가 발생하였다.


5) 절정 : 구글링을 통해 아래 정보를 알 수 있었다.
기본적으로 Scanner 클래스를 이용하여 입력을 받는데 nextInt(); 즉 정수의 경우 공백 ' ', 엔터 \n 에 따라 값을 분리하여 가져오게 된다.
(ex : 2와 5입력 => 2' ' 5 또는 2 \n 5)

 System.out.print("첫 번째 숫자를 입력하세요: ");
                firstNumber = scanner.nextInt();

위 경우를 보면 .nextInt() 를 통해 정수를 입력 받는데 예를들어
x + \n 과 같이 입력을 하면 원래는 x 가 정수여야 하지만 일치하지 않기 때문에 예외가 발생한다. 하지만 버퍼에는 사용되지 않은 \n 이 남게 되며 이 값이 다음 반복문 실행 시 자동으로 위 문장의 firstNumber 변수에 들어가면서 무한적으로 예외가 발생하게 되는 것이다.

따라서 아래와 같이 scanner.nextLine() 을 통해서 버퍼를 비우고 새로운 입력을 받은 준비를 하는 것이 올바른 방식이다.

catch(InputMismatchException e){
                System.out.println("양의 정수가 아닌 이상한 값이 들어옴");
                scanner.nextLine(); // 버퍼 비움 (안 그러면 무한 루프 발생)
           }

결과 :


6) 결말 : 생각보다 이런경우가 앞으로 java, spring 개발을 하면서 많이 만날 것 같다. 해당 문제가 발생 시 유연하게 대처하기 위해서 이러한 지식을 잘가지고 활용 할 수 있도록 해야겠다.


예외 설명

1) 0으로 나누는 예외 처리

case "/":
   if(secondNumber == 0){
           throw new ArithmeticException();
           // 0으로 나뉘는 경우 예외 발생
}
            result = (double) firstNumber / secondNumber;
            break;
  catch(ArithmeticException e){
                System.out.println("0으로 나눌 수 없습니다.");
            }

기본적으로 제공하는 예외인 ArithmeticException()secondNumber 가 0인 경우 발생 시킴으로서 해당 예외를 처리하도록 catch 문에 위와 가치 작성하였다.

2) 음의 정수 입력 시 예외 처리

 if(firstNumber < 0 || secondNumber < 0){
                    System.out.println("음의 정수를 입력함. 양의 정수를 입력해주세요");
                    continue;
                }

음의 정수는 입력을 허용하지 않으므로 위와 같은 조건문을 이용하여 로직 처리를 하였다. 예외를 발생시키지는 않고 반복문을 다음 step 으로 넘어가도록 설계하였다.

3) 올바르지 않은 연산자 예외 처리

   default:
      System.out.println("올바른 연산자를 입력해주세요");
      continue;

이부분은 예외처리 라기 보다는 default를 이용한 간단한 로직 처리인 것 같다. +,-,*,/ 외의 문자가 입력된 경우는 경고 문자를 출력하고 continue를 이용하여 반복문을 계속 돌 수 있도록 설계하였다.

4) 숫자가 아닌 다른 문자가 입력된 경우

catch(InputMismatchException e){
                System.out.println("양의 정수가 아닌 이상한 값이 들어옴");
                scanner.nextLine(); }// 버퍼 비움 (안 그러면 무한 루프 발생) 

Scanner 를 통해 입력 받아야 하는 정수가 정수 형이 아닌 경우 발생하는 예외에 대한 처리이다.

전체 코드

github :

Lv1 :

https://github.com/wootaepark/JavaCalculatorAssignment/tree/main/Calculator/src/calculatorLv1

Lv2 :
https://github.com/wootaepark/JavaCalculatorAssignment/tree/main/Calculator/src/calculatorLv2

Lv3 :
https://github.com/wootaepark/JavaCalculatorAssignment/tree/main/Calculator/src/calculatorLv3

=> 세개의 레벨 모두의 계산기에서 위와 같이 scanner.nextLine() 을 이용하여 버퍼를 비워주지 않으면 문제가 발생하거나, 출력이 올바르게 되지 않는 경우가 있기 때문에 이 사실을 유념하고 가면 좋을 것 같다.

profile
잘 부탁드립니다.

0개의 댓글