[트러블 슈팅] 키오스크 과제 with Java

2025. 1. 13. 23:38프로그래밍 언어/Java

개요

키오스크 필수 과제 중 생긴 문제에 대해서 트러블 슈팅을 작성을 해보았다.

 

 

 

문제

1.  ShackBurger	 |  W 6.9	 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거 
2.  SmokeShack	 |  W 8.9	 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거 
3.  Cheeseburger |  W 6.9	 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거 
4.  Hamburger	 |  W 5.4	 | 비프패티를 기반으로 야채가 들어간 기본버거 
0. 종료			 | 종료
메뉴를 선택해주세요.
Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:939)
	at java.base/java.util.Scanner.next(Scanner.java:1594)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
	at com.example.kiosk3.Kiosk.selectMenu(Kiosk.java:53)
	at com.example.kiosk3.Kiosk.start(Kiosk.java:28)
	at com.example.kiosk3.Main.main(Main.java:10)

> Task :com.example.kiosk3.Main.main() FAILED

Execution failed for task ':com.example.kiosk3.Main.main()'.
> Process 'command '/usr/lib/jvm/java-17-openjdk-amd64/bin/java'' finished with non-zero exit value 1

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 1m 26s
2 actionable tasks: 2 executed

 

입력을 받을 때, 숫자가 아닌 문자열을 입력을 받을 경우 생기는 문제가 있었다.

 

Exception 내용을 확인을 해보니 InputMismatchException 이(가) 발생하였다.

 

java.util.InputMismatchException이 발생하는 이유는

Scanner에서 값을  입력받아야 하는데, 그때 잘못된 Type을 입력을 받으면 발생한다고 한다.

 

해결 방법.1

프로그램은 런타임 Exception이 발생을 한다면 프로그램이 종료가 되기 때문에 반드시 막아야하는 Exception이다.

 

막는 방법으로 try - catch문을 사용하여 프로그램이 관리을 할 수 있는 Exception으로 만드는 것이 중요하다.

try {
	electNum = sc.nextInt();
	if( !( 0 <= selectNum && selectNum <= menuItems.size() ) ) throw new NumberFormatException("메뉴에 없습니다.");
} catch ( NumberFormatException e ) {
	System.out.println(e.getMessage());
	continue;
}

 

프로그램 중에 사용자에게 Scanner을 사용하여 입력을 받는 곳이 여기 밖에 없기 때문에 여기서 문제가 난다고 판단을 하였다.

 

 

그러면 catch문에 InputMismatchException을 추가하여 돌려보자.

 

 

디버그 모드에서 Exception이 발히는 모습을 확인할 수 있었다.

 

 

해결 방법.2

 

 

하지만 실행을 하면 계속 null값이 들어가서 끝없이 반복이 된다는 점을 확인하였다.

 

왜 그런지 디버그 모드를 통해서 찾아보자.

 

디버그 모드를 통해서 Scanner 객체의 buf안에 값이 없어지지 않는 모습을 확인 할 수 있었다.

System.out.println("메뉴를 선택해주세요.");
try {
	selectNum = sc.nextInt();
	if( !( 0 <= selectNum && selectNum <= menuItems.size() ) ) throw new NumberFormatException("메뉴에 없습니다.");
	} catch ( NumberFormatException e ) {
		System.out.println(e.getMessage());
		continue;
	} catch ( InputMismatchException e ) {
		System.out.println("잘못된 입력입니다.");
		sc.next();
		continue;
}

 

sc.nextInt 뒤에 \n값이 온다면 버퍼가 비워지지 않는 모습을 확인하였다.

 

그래서 buf를 지워주기 위해서 InputMismatchException이 발생을 한다면

스캐너를 비워주기 위해 sc.next() 을 한번 더 출력을 해줘서 다음 줄에 받도록 만들어주었다.

 

 

결과

잘 해결이 된 모습이다.

 

생각보다 자바에서 Scanner을 사용할 때 버퍼에서 오는 문제가 많은 듯하다.

 

보통 블로그 주인장이 겪은 Scanner 버퍼의 문제는 다음 인풋이 안먹히는 문제가 대다수였다.

 

이번에 생긴 문제을 생각을 간단하게 해보면

 

아마 첫 sc.nextInt() 을 입력을 받을 때 "t\n" 값이 들어갔을 때

바로 InputMismatchException이 발생을 할 것이다.

그러면 다음 while문을 통해서 다음 인풋때 똑같이 버퍼가 안비워져 있으니 똑같은 Exception이 발생을 하고

이것이 반복이 되는 것으로 추정이 된다.

 

느낀점

이런 것을 생각보다 빠르게 잡는 모습을 보니 

내배캠을 하면서 발전을 하고 있는 자신의 모습이 보이는 듯하다.

더 열심히 해야겠다.