내일배움캠프/TIL
2024 07 22 TIL : [Java] scanner 버퍼를 비워주기
동성만능크리너
2024. 7. 22. 21:19
자바 기초 문법 주차가 시작되고, 강의를 들으면서 숙제로 받은 "레시피 이름, 별점, 레시피 내용"을 입력받고 출력하는 간단한 프로그램을 만들다가, 이해가 되질 않는 부분이 있었다.
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//스캐너 객체 생성
Scanner sc = new Scanner(System.in);
String recipeName = sc.nextLine();
double recipeRating = sc.nextDouble();
//실수로 받은 별점을 정수로 변환
int irecipeRating = (int)recipeRating;
ArrayList<String> recipeContents = new ArrayList<>();
//레시피 한줄씩 10번 입력받기
for (int i = 0; i < 10; i++) {
recipeContents.add(sc.nextLine());
}
System.out.printf("[%s]\n",recipeName);
System.out.printf("별점 : %d (%d%%) \n",irecipeRating,irecipeRating*20);
for (int i = 0; i< 10; i++) {
System.out.printf("%d. %s\n",i+1,recipeContents.get(i));
}
}
}
이런 코드를 짜고 입력을 쭉쭉하면 9번째 레시피를 입력하고나면 입력을 그만 받아버리고, 0번째 인덱스를 0으로 출력한 뒤, 그대로 10개를 만들어버리는 것이었다.
도대체 왜 이러나 싶어서 scanner 사용법이 적힌 글들을 찾아보다가, nextDouble()을 사용했으면, 입력한 실수만 들어가고 개행문자 '\n'은 버퍼에 남아서 다음 입력에 사용된다는 것이다. 그리고 이를 해결하기 위해 nextDouble()과 같이 숫자형을 입력받거나 했으면, nextLine()을 한 번 써서 버퍼를 비워주면 문제없이 입력받은대로 출력해낼 수 있다.
Scanner sc = new Scanner(System.in);
String recipeName = sc.nextLine();
double recipeRating = sc.nextDouble();
sc.nextLine(); //버퍼를 비워주기
//실수로 받은 별점을 정수로 변환
int irecipeRating = (int)recipeRating;
ArrayList<String> recipeContents = new ArrayList<>();
혹시 숫자형을 입력 받은 경우 말고도 스캐너를 쓸 때, 버퍼를 비워줘야 하는 경우는 없나 궁금해서 GPT에 물어봤더니
더보기
- 숫자형 입력 후 문자열 입력 시:
- 앞서 설명한 것처럼, nextInt(), nextDouble() 등 숫자형 입력 메서드는 숫자만 읽고 줄바꿈 문자는 버퍼에 남깁니다. 따라서 다음 nextLine() 호출 전에 버퍼를 비워줘야 합니다.
- 문자열 입력 후 줄바꿈 문자를 무시하고 싶을 때:
- nextLine() 메서드는 줄바꿈 문자를 포함한 나머지 줄을 읽습니다. 만약 특정 조건 후 줄바꿈 문자만 제거하고 싶다면 nextLine()을 한 번 호출하여 버퍼를 비워줄 수 있습니다.
- 특정 토큰 처리 후 다음 줄을 읽을 때:
- next(), nextInt(), nextDouble() 등의 메서드는 공백이나 줄바꿈 문자를 구분자로 사용하여 입력을 처리합니다. 이러한 메서드들 후에 다음 줄을 완전히 읽고 싶을 때는 nextLine()을 호출하여 버퍼를 비워줘야 합니다.
- 사용자 입력 패턴이 변경될 때:
- 예를 들어, 숫자형 입력을 받다가 문자열 입력을 받거나, 여러 라인의 문자열 입력을 받다가 숫자형 입력을 받을 때, 줄바꿈 문자를 처리해야 할 필요가 생길 수 있습니다.
라는 답변을 받았다. 이를 잘 숙지해서 앞으로는 저런 상황 이후, 버퍼를 받아서 의도한 대로 프로그램이 동작할 수 있게 잘 써야겠다.