Notice
Recent Posts
Link
Recent Comments
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

지니의 개발로그

[Java] 버퍼의 개행문자 제거. 라인을 읽어주고 버리기 (TIL #28일차) 본문

내일배움캠프

[Java] 버퍼의 개행문자 제거. 라인을 읽어주고 버리기 (TIL #28일차)

지니♥︎ 2024. 5. 14. 09:50

🚩 20240513 TIL 내일배움캠프 #28일차

 

🔴 문제

package scanner.ex;

import java.util.Scanner;

public class ScannerWhileEx1 {
public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    while(true) {
        System.out.print("이름을 입력하세요 (종료를 입력하면 종료) : ");
        String userName = sc.nextLine();

        if (userName.equals("종료")) {
            System.out.println("프로그램을 종료합니다.");
            break;
        }

        System.out.print("나이를 입력하세요 : ");
        int userAge = sc.nextInt();
        if (userAge <= 0 || userAge >= 150) {
            System.out.println("잘못된 나이를 입력하셨습니다. 다시 입력해주세요.");
        }

            System.out.println("입력한 이름 : " + userName + ", 나이 : " + userAge);

    }

}
}

 

 

콘솔창에 실행 시 두번 째 반복부터 이름 입력을 생략하고 '나이를 입력하세요'가 나온다.

 

🟠 분석

 

Scanner의 nextInt() 메소드는 입력 스트림에서 정수를 읽어오지만,

입력 뒤에 오는 개행문자는 버퍼에 남아있게 된다.

sc.nextInt() 메소드 사용 후 버퍼에 남아있는 개행문자("\n") 때문에
바로 다음 반복으로 넘어가게 된다.

 

오류의 로직을 자세히 뜯어보면 다음과 같다.

  1. 프로그램이 실행되면 "이름을 입력하세요" 메시지가 출력된다.
  2. 사용자가 이름을 입력하고 엔터를 치면, sc.nextLine()이 이름과 엔터의 개행문자("\n")를 모두 읽어온다.
  3. "나이를 입력하세요" 메시지가 출력된다.
  4. 사용자가 나이를 입력하고 엔터를 치면, sc.nextInt()는 정수 부분만 읽고, 엔터의 개행문자("\n")는 버퍼에 남겨둔다.
  5. System.out.println("입력한 이름: " + userName + ", 나이: " + userAge); 코드가 실행되어 입력한 이름과 나이가 출력된다.
  6. 반복문이 다시 시작되고, "이름을 입력하세요" 메시지가 출력된다.
  7. 그런데 sc.nextLine()이 호출되면, 이전에 버퍼에 남아있던 개행문자("\n")가 읽혀진다.
  8. 프로그램은 이 개행문자를 유효한 이름 입력으로 인식한다.
  9. "나이를 입력하세요" 메시지가 출력되면서 바로 나이를 입력받기 위한 다음 반복으로 넘어가게 된다.

 

🟡 시도

 

nextInt() 후에 sc.nextLine()을 한 번 더 호출하여 버퍼의 개행문자를 제거해주었다.

 

🟢 배움

자바의 Scanner 클래스를 사용할 때, 

nextInt() 메서드는 사용자가 입력한 정수만을 읽어오고 그 뒤에 입력된 개행문자(\n)는 버퍼에 남겨두기 때문에
이후 nextLine() 호출 시 버퍼에 남은 개행문자가 읽혀져서

해당 메서드에서 입력을 못받고 다음 코드로 넘어가는 문제가 발생한다.

 

개행문자를 남겨두는 메서드 사용 후에

nextLine()을 한 번 더 호출하여 버퍼에 남아있는 개행문자를 읽어내고 제거하여 문제를 해결 할 수 있다.

 

* 개행 문자를 남겨두는 메서드 예시 : nextInt(), nextFloat(), nextDouble(), nextByte(), nextShort(), nextLong()

 

반복문을 사용할 때 이러한 데이터 처리 로직에 오류가 발생하지 않도록 주의해야 한다.

 

위와같이 프로그래밍 언어와 그 기능들을 사용할 때

숨겨진 동작 원리를 이해하고 사용하는 것이 중요한 것 같다.