[JAVA] next() 시리즈 정리

Jongyhyuk Kim·2021년 2월 10일
3

TIP

목록 보기
1/3
post-thumbnail
post-custom-banner

매일 알고리즘 Test를 풀다보면 항상 마주하게 되는 Scanner 클래스
물론 받아오는 데이터량이 많다면 BufferedReader를 써야겠지만 데이터량이 적다면 속도면에서 크게 차이가 없다는 점과 불편한 형변환을 하지않아도 된다는 점을 바탕으로 자주 쓰곤 한다.

하지만 next()와 nextLine()을 혼용하면서 발생하는 문제가 여김없이 발생하였기에 마침 시간도 여유가 있는 오늘 정리를 해보게되었다.

Scanner() Method

  • next(): String, 다음 토큰을 문자열로 return
  • nextLine(): String, '\n'을 포함하는 한 line을 읽고 '\n'을 버린 나머지만 return
  • nexyByte(): byte, 다음 토큰을 byte 타입으로 return
  • nextShort(): short, 다음 토큰을 short 타입으로 return
  • nextInt(): int, 다음 토큰을 int 타입으로 return
  • nextLong(): long, 다음 토큰을 float 타입으로 return
  • nextDouble(): double, 다음 토큰을 double 타입으로 return
  • close(): void, Scanner의 사용 종료
  • hasNext(): boolean, 현재 입력된 토큰이 있으면 true, 아니면 새로운 입력이 들어올 때까지 무한정 기다리면서 새로운 입력이 들어오면 그 때 true return, ctrl+z 키가 입력되면 입력 끝으로 false return

자주 발생하는 문제

nextLine(): String, '\n'을 포함하는 한 line을 읽고 '\n'을 버린 나머지만 return

이녀색 때문에 문제가 자주 발생하는데 그 문제는 다음과 같다.

import java.util.Scanner; 
public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
 
        int num;
        String str;
        System.out.println("num입력");
        num = input.nextInt();
        System.out.println("str입력");
        str = input.nextLine();
 
        System.out.println("num : " + num);
        System.out.println("str : " + str);
        input.close();
    }
}

예시 1

출처: https://sleepyeyes.tistory.com/22

위 코드를 보면 str 값을 입력하기 전에 입력이 종료되며 바로 출력 값이 나오는 것을 확인할 수 있다.

왜 발생하는가?

nextLine()은 개행문자 '\n'을 포함하여 입력받는다.
이를 다시 풀어 쓴다면 nextInt() 입력 값 10을 받고 Enter를 입력했다면 Buffer에 5\n이 올라가고 nextInt()는 개행문자 '\n'을 제외하고 5만 가져온다.
그러나 바로 다음에 나오는 nextLine()은 개행문자를 포함하여 입력받기 때문에 이미 Buffer에 올라와있는 '\n'을 가져오는 결과를 보여준다.

그렇기 때문에
1. next() method를 혼용하여 쓴다면 nextLine() 이전에 입력 받는 값을 고려하여 next()로 대체하는 것이 좋은 대안이 될 수 있을 것이고
2. nextLine()을 뒤에 써야한다면 아래와 같이 buffer를 정리하기 위한 nextLine()을 실행해주는 방법이 있다.

int num = sc.nextInt();
sc.nextLine();
String str = sc.nextLine();

예시2

import java.util.Scanner; 
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
 
        String str1;
        String str2;
        System.out.println("str1입력");
        str1 = input.next(); //예시2
        //str1 = input.nextLine(); //예시3
 
        System.out.println("str2입력");
        str2 = input.nextLine(); //예시2
        //str2 = //예시3
 
        System.out.println("str1 : " + str1);
        System.out.println("str2 : " + str2);
        input.close();
    }
}

예시1과 연장선으로 예시2의 입력값을 확인해 보면 next()는 개행문자를 받기 전까지 입력할 수 있으나 space 분리자를 기준으로 값을 입력받아 space 전까지의 값이 str1에 들어가고 buffer에 올라가고 nextLine()은 개행문자를 포함하여 받아오니 buffer에 올라간 나머지 값이 str2에 들어가 프로그램이 종료된다.

예시3

next()와 nextLine()의 순서를 바꿔 입력받아보면 위와 같이 깔끔하게 출력됨을 확인할 수 있다.

결론

next()와 nextLine()의 경우 둘다 문자열을 받을 수 있는 method이지만 nextLine()이 개행문자를 포함하여 받아오기 때문에 각별한 주의가 필요하다.!
그러나 space와 같은 공백문자를 포함하여 입력 값을 받고 싶은 경우 nextLine()을 활용하는 것이 좋은 선택이 될 수 있다.

참고 사이트
https://devlog-wjdrbs96.tistory.com/80

profile
Bellhyuk, Bottom out
post-custom-banner

0개의 댓글