[TIL] 2026.09.22

ddee·2026년 9월 22일

문제 상황

계산기에 숫자가 아닌 값을 입력하면 에러 메시지와 함꼐 프로그램이 그대로 종료되었다. 입력 위치에 따라 서로 다른 예외가 발생했다.

케이스 1. 첫 번째 숫자에 abc입력

첫 번째 숫자를 입력하세요 (종료하려면 exit):abc
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
	at java.base/java.lang.NumberFormatException.forInputString(...)
	at java.base/java.lang.Integer.parseInt(...)
	at com.example.calculator.App.main(App.java:20)

케이스 2. 두 번째 숫자에 abc 입력

첫 번째 숫자를 입력하세요 (종료하려면 exit):10
두 번째 숫자를 입력하세요:abc
Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(...)
	at java.base/java.util.Scanner.next(...)
	at java.base/java.util.Scanner.nextInt(...)
	at com.example.calculator.App.main(App.java:23)

계산기는 사용자가 원할 때까지 계속 동작해야 하는데, 입력 실수 한 번에 그동안 저장한 계산 기록까지 모두 날아가 버린다.

원인 분석

수정 전 코드

String input1 = sc.next();
// ... exit 검사 ...
int num1 = Integer.parseInt(input1);   // L20 → NumberFormatException

System.out.print("두 번째 숫자를 입력하세요:");
int num2 = sc.nextInt();               // L23 → InputMismatchException

첫 번째 숫자 = next() + Integer.parseInt() : 문자열을 먼저 받고, 나중에 정수로 변환 : NumberFormatException

두 번째 숫자 = sc.nextInt() : Scanner가 읽는 순간 정수인지 검사 : InputMismatchException

첫 번째 숫자는 "exit" 입력을 처리하려고 String으로 받았기 때문에 입력 자체는 성공하고, 변환 단계에서 실패한다. 두 번째 숫자는 Scanner가 읽는 단계에서 바로 실패한다. 실패 지점이 다르니 예외 종류도 달라진 것이다.

그리고 기존 try-catch는 calculate() 호출 부분만 감싸고 있어서, 그 위에서 터진 이 두 예외는 아무도 잡지 못하고 main 밖으로 빠져나가 프로그램이 종료되었다.

해결 과정

입력 방식을 next() + parseInt()로 통일

두 숫자 모두 next()로 문자열을 먼저 받고, 변환은 Integer.parseInt()로 한다. next()는 입력을 항상 가져가기 때문에 버퍼에 찌꺼기가 남지 않고, 예외도 NumberFormatException 하나만 처리하면 된다.

수정 전/ 후 비교

수정 전

while(true){
    System.out.print("첫 번째 숫자를 입력하세요 (종료하려면 exit):");
    String input1 = sc.next();

    if (input1.equalsIgnoreCase("exit")){
        System.out.println("계산기를 종료합니다.");
        break;
    }

    int num1 = Integer.parseInt(input1);          // 예외 처리 없음

    System.out.print("두 번째 숫자를 입력하세요:");
    int num2 = sc.nextInt();                      // 예외 처리 없음, 방식도 다름

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

    try{
        int result = calculator.calculate(num1,num2,operator);
        System.out.println("결과: "+result);
    }catch (ArithmeticException | IllegalArgumentException e){
        System.out.println(e.getMessage());
    }
    // ...
}

수정 후

while(true){
    System.out.print("첫 번째 숫자를 입력하세요 (종료하려면 exit):");
    String input1 = sc.next();

    if (input1.equalsIgnoreCase("exit")){
        System.out.println("계산기를 종료합니다.");
        break;
    }

    System.out.print("두 번째 숫자를 입력하세요:");
    String input2 = sc.next();                    // ① 두 번째도 문자열로 받기

    int num1, num2;
    try {
        num1 = Integer.parseInt(input1);          // ② 변환을 try 안에서
        num2 = Integer.parseInt(input2);
    } catch (NumberFormatException e) {
        System.out.println("숫자를 입력해야 합니다. 처음부터 다시 입력해주세요.");
        continue;                                 // ③ 이번 계산은 건너뛰고 처음으로
    }

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

    try{
        int result = calculator.calculate(num1,num2,operator);
        System.out.println("결과: "+result);
    }catch (ArithmeticException | IllegalArgumentException e){
        System.out.println(e.getMessage());
    }
    // ...
}

0개의 댓글