Troubleshooting: 무엇이 문제였는가?/본캠프 2주 차: 키오스크 만들기

1단계: "반복문 밖에서 변수를 선언했더니 햄버거가 비처럼 내리네!"

writingforever162 2024. 11. 24. 18:54

[문제]

package com.example.kiosk;

import java.util.*;

public class KioskLvOne {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println();
        System.out.println("[ GRILL&THRILL MENU ]");

        double[] price = new double[4];
        price[0] = 6.9;
        price[1] = 8.9;
        price[2] = 6.9;
        price[3] = 5.4;

        String[] priceString = new String[4];
        priceString[0] = Double.toString(price[0]);
        priceString[1] = Double.toString(price[1]);
        priceString[2] = Double.toString(price[2]);
        priceString[3] = Double.toString(price[3]);

        String[][] hamburgerMenu =
                {
                        {"1. ", "BasicBurger", "      | W ", priceString[0], " | ", "토마토, 양상추, 쉑소스가 토핑된 치즈버거"},
                        {"2. ", "GrilledThrill", "    | W ", priceString[1], " | ", "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"},
                        {"3. ", "Cheeseburger", "     | W ", priceString[2], " | ", "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"},
                        {"4. ", "Hamburger", "        | W ", priceString[3], " | ", "비프패티를 기반으로 야채가 들어간 기본버거"},
                        {"0. ", "종료", "              | ", "종료"}
                };

        for (int i = 0; i < hamburgerMenu.length; i++) {
            for (int j = 0; j < hamburgerMenu[i].length; j++) {
                System.out.print(hamburgerMenu[i][j]);
            }
            System.out.println();
        }

        System.out.println();
        System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
        System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
        int menuNumber = sc.nextInt();
        System.out.println();
        
        boolean flag = true;
        while (flag) {
            switch (menuNumber) {
                case 1:
                    System.out.println(hamburgerMenu[0][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[0]*1000));
                    System.out.println("원입니다.");
                    break;

                case 2:
                    System.out.println(hamburgerMenu[1][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[1]*1000));
                    System.out.println("원입니다.");
                    break;

                case 3:
                    System.out.println(hamburgerMenu[2][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[2]*1000));
                    System.out.println("원입니다.");
                    break;

                case 4:
                    System.out.println(hamburgerMenu[3][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[3]*1000));
                    System.out.println("원입니다.");
                    break;

                case 0:
                    flag = false;
                    System.out.println("0을 누르셨습니다. 프로그램을 종료합니다.");
                    break;

                default:
                    System.out.println("6 이상인 번호를 눌렀습니다. 번호를 다시 눌러주세요. 프로그램을 종료합니다.");
                    System.exit(0);
            }
        }
    }
}

하늘에서 햄버거가 소나기처럼 우수수 떨어지면 이런 기분이 들까 싶었다. 분명 switch-case문 안에 break;도 모두 입력했건만, 1을 눌렀다가 햄버거가 끝없이 쏟아져 내렸다. 까마득한 위에서 떨어지는 햄버거는 우박 같았다. 엄청 아팠다.

 

[원인]

System.out.println();
System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
int menuNumber = sc.nextInt();
System.out.println();

원인은 정수형 int 타입으로 선언한 변수 menuNumber가, 위에 따로 빼둔 코드 5줄이 while문 바깥에 있는 데에 있었다.

package com.example.kiosk;

import java.util.*;

public class KioskLvOne {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println();
        System.out.println("[ GRILL&THRILL MENU ]");

        double[] price = new double[4];
        price[0] = 6.9;
        price[1] = 8.9;
        price[2] = 6.9;
        price[3] = 5.4;

        String[] priceString = new String[4];
        priceString[0] = Double.toString(price[0]);
        priceString[1] = Double.toString(price[1]);
        priceString[2] = Double.toString(price[2]);
        priceString[3] = Double.toString(price[3]);

        String[][] hamburgerMenu =
                {
                        {"1. ", "BasicBurger", "      | W ", priceString[0], " | ", "토마토, 양상추, 쉑소스가 토핑된 치즈버거"},
                        {"2. ", "GrilledThrill", "    | W ", priceString[1], " | ", "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"},
                        {"3. ", "Cheeseburger", "     | W ", priceString[2], " | ", "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"},
                        {"4. ", "Hamburger", "        | W ", priceString[3], " | ", "비프패티를 기반으로 야채가 들어간 기본버거"},
                        {"0. ", "종료", "              | ", "종료"}
                };

        for (int i = 0; i < hamburgerMenu.length; i++) {
            for (int j = 0; j < hamburgerMenu[i].length; j++) {
                System.out.print(hamburgerMenu[i][j]);
            }
            System.out.println();
        }

        System.out.println();
        System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
        System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
        int menuNumber = sc.nextInt();
        System.out.println();
        // [오답] while문 바깥에 위치
        // [정답] while문 안에 있어야 함

        boolean flag = true;
        while (flag) {
            switch (menuNumber) {
                case 1:
                    System.out.println(hamburgerMenu[0][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[0]*1000));
                    System.out.println("원입니다.");
                    break;

                case 2:
                    System.out.println(hamburgerMenu[1][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[1]*1000));
                    System.out.println("원입니다.");
                    break;

                case 3:
                    System.out.println(hamburgerMenu[2][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[2]*1000));
                    System.out.println("원입니다.");
                    break;

                case 4:
                    System.out.println(hamburgerMenu[3][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[3]*1000));
                    System.out.println("원입니다.");
                    break;

                case 0:
                    flag = false;
                    System.out.println("0을 누르셨습니다. 프로그램을 종료합니다.");
                    break;

                default:
                    System.out.println("6 이상인 번호를 눌렀습니다. 번호를 다시 눌러주세요. 프로그램을 종료합니다.");
                    System.exit(0);
            }
        }
    }
}

변수 menuNumber가 while문 바깥에 있으니, 반복문이 끝날 때마다 변수 선언과 초기화가 이루어지지 않아 무한으로 돌았다. 반복문 안에서 변수를 선언하고 초기화해야 반복문이 끝날 때마다 변수 선언과 초기화 또한 새롭게 이루어져서 무한 반복의 늪에 빠지는 일이 없었다. 

 

2단계 계산기를 만들 때는 반복문 안에서 객체를 생성하더니, 이번엔 반복문 바깥에서 변수를 선언하고 초기화했다. 이 정도면 청개구리와 친구가 아닌가 싶었다.

 

[해결]

package com.example.kiosk;

import java.util.*;

public class KioskLvOne {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println();
        System.out.println("[ GRILL&THRILL MENU ]");

        double[] price = new double[4];
        price[0] = 6.9;
        price[1] = 8.9;
        price[2] = 6.9;
        price[3] = 5.4;

        String[] priceString = new String[4];
        priceString[0] = Double.toString(price[0]);
        priceString[1] = Double.toString(price[1]);
        priceString[2] = Double.toString(price[2]);
        priceString[3] = Double.toString(price[3]);

        String[][] hamburgerMenu =
                {
                        {"1. ", "BasicBurger", "      | W ", priceString[0], " | ", "토마토, 양상추, 쉑소스가 토핑된 치즈버거"},
                        {"2. ", "GrilledThrill", "    | W ", priceString[1], " | ", "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"},
                        {"3. ", "Cheeseburger", "     | W ", priceString[2], " | ", "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"},
                        {"4. ", "Hamburger", "        | W ", priceString[3], " | ", "비프패티를 기반으로 야채가 들어간 기본버거"},
                        {"0. ", "종료", "              | ", "종료"}
                };

        for (int i = 0; i < hamburgerMenu.length; i++) {
            for (int j = 0; j < hamburgerMenu[i].length; j++) {
                System.out.print(hamburgerMenu[i][j]);
            }
            System.out.println();
        }

        boolean flag = true;
        while (flag) {
            System.out.println();
            System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
            System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
            int menuNumber = sc.nextInt();
            System.out.println();
            // [수정] 반복문 안에서 menuNumber 변수 선언 및 초기화

            switch (menuNumber) {
                case 1:
                    System.out.println(hamburgerMenu[0][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[0]*1000));
                    System.out.println("원입니다.");
                    break;

                case 2:
                    System.out.println(hamburgerMenu[1][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[1]*1000));
                    System.out.println("원입니다.");
                    break;

                case 3:
                    System.out.println(hamburgerMenu[2][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[2]*1000));
                    System.out.println("원입니다.");
                    break;

                case 4:
                    System.out.println(hamburgerMenu[3][1] + " 1개가 선택되었습니다.");
                    System.out.print("가격은 ");
                    System.out.print((int)(price[3]*1000));
                    System.out.println("원입니다.");
                    break;

                case 0:
                    flag = false;
                    System.out.println("0을 누르셨습니다. 프로그램을 종료합니다.");
                    break;

                default:
                    System.out.println("6 이상인 번호를 눌렀습니다. 번호를 다시 눌러주세요. 프로그램을 종료합니다.");
                    System.exit(0);
            }
        }
    }
}

원인을 찾아서 해결한 뒤에는 출력이 무한으로 이루어지지 않고 다시 맨 처음 안내 문구로 돌아갔다. 자바(Java)를 배우는 초반에 이런 실수를 해서 차라리 다행이었다.

 

[수정 전] 무한 반복 오류 1개 발생 

[수정 후] 무한 반복 오류 0개 발생