본문 바로가기
컴퓨터 프로그래밍/Java

[Java] 레시피를 입력, 출력하는 프로그램을 만들어보며 복습하기 ( + ArrList 사용해보기, 입력버퍼 비우기)

by 한33 2024. 7. 23.

강의 마지막 과제 내용으로 레시피를 출력하는 프로그램을 만들어보았다.

 

 


import java.util.Scanner;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<String> cookingArr = new ArrayList<>();

        System.out.println("요리 제목을 입력하세요 : "); //요리 제목 입력
        String menu_name = sc.nextLine();

        System.out.println("1~5 별점을 입력하세요 (소수점 가능)"); //별점 입력
        double star = sc.nextDouble();
        int intStar = (int)star;
        double percentStar = ( intStar *100 /5  );


        sc.nextLine(); //입력 버퍼 지우기
            System.out.println("요리 방법을 입력해주세요."); //요리 방법 입력
            for (int i = 1; i <11; i++) {
                System.out.print(i + ".");
                String cookingNum = sc.nextLine();
                cookingArr.add(cookingNum);
            }

        System.out.println("-------입력이 완료되었습니다-------");
        System.out.println("[" + menu_name + "]");
        System.out.println("별점 : " + intStar + " (" + percentStar + "%)");
        for (int i=0; i<cookingArr.size(); i++) {
            System.out.println(i+1 + ". " +cookingArr.get(i));
        }
    }
}

 

위 과제에서 해결하기 위해 겪었던 부분들을 정리해보았다.

 

1.동적 변수 사용 해결을 위해 ArrayList 

import java.util.ArrayList;

* 유틸 import

ArrayList<String> cookingArr = new ArrayList<>();

* ArrayList 변수 선언

cookingArr.add(cookingNum);

* 배열 안에 요소 추가

for (int i=0; i<cookingArr.size(); i++) {
    System.out.println(i + ". " +cookingArr.get(i));
}

* 배열 안에 요소 출력

 

기존에 javascript 로 개인 프로젝트를 하면서 아래와 같이 동적 변수를 선언한 경험이 있었다.

story-photo-add-comment-input-area0<%= i %>

 

입력한 요리방법 순서를 배열에 저장해놨기 때문에 이를 반복문을 이용해 순서대로 출력하기를 원했다.

 

검색을 해서 알아본 결과 ArrayList 유틸을 이용해서 해결을 할 수 있었다.

 

2. 띄어쓰기를 포함한 문자열 입력받기

String menu_name = sc.nextLine();

 

우선 문자열을 받기 위해 변수 타입을 String 으로 선언했고,

 

원래대로 sc.next(); 만 입력하면 띄어쓰기를 입력 시 엔터와 같은 효과를 냈었다.

 

이럴 때는 nextLine(); 으로 넣어주면 띄어쓰기도 포함해서 입력을 할 수 있었다.

 

3. 백분율 수 저장하기

double star = sc.nextDouble();
int intStar = (int)star;
double percentStar = ( intStar *100 /5  );

 

제일 막혔던 부분이었다.

 

double percentStar = ( intStar /5 *100  );

 

기존에 위와 같이 코드를 짰는데, 이대로 진행하면 출력시에 결과가 계속 0이 나왔다.

 

왜 0이 나오는지 고민을 계속 해봤고 옆에 빨간 원 포인트를 주어 Debug 를 이용해서 알아내봤다.

 

이유는 1~5 사이에 숫자를 입력했기 때문에 이를 5로 나누면 5를 입력하지 않은 이상 0.xx 식으로 소수가 입력되었을 것이다.

 

하지만 두 번째 줄 코드로 인해서 int 타입으로 형상이 변경되면서 소수점은 사라지게 된다.

 

그 이후에 100 을 곱하면 0*100 이니까 계속 0이 나왔던 것이다.

 

이를 해결하기 위해서 곱의 순서를 바꿨다.

 

먼저 100을 곱해서 정수에서 5를 나누도록 바꿨다.

 

그럼에도 출력은 20.0% 꼴로 소수점이 나와야하기 때문에, 또 많은 용량이 필요하지 않기 때문에 double 타입을 선택해서 선언했다.

 

4. 입력 버퍼 지우기

 

내 코드대로면 문제없이 순서대로 1. 만 출력이 된 다음 첫 번째 요리방법을 입력한 후에 2. 가 출력되어야 했다.

 

근데 자꾸 저런 문제가 반복해서 알아봤다.

 

double star = sc.nextDouble();

 

기존 이 단계에서 nextDouble() 메서드 사용 후, 입력 버퍼에 남아있는 줄바꿈 문자를 nextLine() 을 호출하면서 소비하게 된 것이다. 그래서 1. 다음으로 자동으로 줄바꿈이 되어 2. 까지 출력이 된 것이다.

 

sc.nextLine(); //입력 버퍼 지우기
    System.out.println("요리 방법을 입력해주세요."); //요리 방법 입력
    for (int i = 1; i <11; i++) {
        System.out.print(i + ".");
        String cookingNum = sc.nextLine();
        cookingArr.add(cookingNum);
    }

 

맨 위에 입력 버퍼를 한 번 지워주고 시작했다. 초기화라고 생각하면 편할 것 같다.

 

그럼 왜 menu_name 선언 시 사용되었던 입력 메소드는 star 선언 시 왜 영향을 미치지 않았을까, 그럼 star 선언 전에도 입력 버퍼를 초기화했어야 하는 게 아니었을까.

 

각 메서드마다 입력 버퍼를 다루는 방식에 대한 이해가 필요했다.

 

String menu_name = sc.nextLine();

 

 

nextLine() 메서드:

  • 줄바꿈 문자(\n)까지의 모든 문자열을 읽고, 줄바꿈 문자도 소비한다.
  • 즉, 줄바꿈 문자까지 모두 처리하여 입력 버퍼를 완전히 비운다.

 

double star = sc.nextDouble();

 

nextDouble() 메서드:

  • 공백이나 줄바꿈 문자 전까지의 숫자를 읽는다.
  • 줄바꿈 문자는 소비하지 않고 입력 버퍼에 남겨둔다.

그러므로 nextDouble() 메소드를 사용하기 전에는 입력 버퍼를 비워줄 필요가 없었던 것이다.