본문 바로가기

공부

scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"); 를 하는 이유 ..

문제

해커랭크를 풀다가 낯선 표현이 있었다.

  • 두 개의 입력값을 받을 때
 input : 1 2 
 
 String[] ab = scanner.nextLine().split(" ");
 int a = Integer.parseInt(ab[0]);
 int b = Integer.parseInt(ab[1]);
  • 세 개의 입력값을 받을 때
input : 1 2 3

String[] applesItems = scanner.nextLine().split(" ");
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

for (int i = 0; i < m; i++) {
    int applesItem = Integer.parseInt(applesItems[i]);
    apples[i] = applesItem;
}
  • 세 개의 입력값을 받았을 때, scanner.skip 을 왜 해야 하는지 궁금했다...

 

해결

Scanner.nextLine()의 정규표현식은 이렇다.
private static final String LINE_SEPARATOR_PATTERN =
                                           "\r\n|[\n\r\u2028\u2029\u0085]";
  • /r/n Windows line ending
  • /n UNIX line ending
  • /r Macintosh (pre-OSX) line ending
  • \u2028 LINE SEPARATOR
  • \u2029 PARAGRAPH SEPARATOR
  • \u0085 NEXT LINE(NEL)
유니코드
 유니코드의 새줄 문자 
LS줄 구분자(Line Separator)U+2028
PS문단 구분자(Paragraph Separator)U+2029
NEL다음 줄(Next Line)U+0085

테스트코드

첫째 줄은 과일, 둘째 줄은 커피를 입력받아 출력을 하는 코드

  • scanner.skip을 사용하지 않았을 때
input : 
banana apple watermelon

latte americano
output :
[banana, apple, watermelon]
[]
 public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] fruit = scanner.nextLine().split(" ");
        String[] coffee = scanner.nextLine().split(" ");

        System.out.println(Arrays.toString(fruit));
        System.out.println(Arrays.toString(coffee));
 }
  • scanner.skip을 사용
input : 
banana apple watermelon

latte americano
[banana, apple, watermelon]
[latte, americano]
public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] fruit = scanner.nextLine().split(" ");
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
        String[] coffee = scanner.nextLine().split(" ");
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

        System.out.println(Arrays.toString(fruit));
        System.out.println(Arrays.toString(coffee));
    }
  • scanner.nextLine()은 줄 구분자, 문단 구분자, 다음줄을 한 줄로 인식하여 읽는다.
  • 여러 줄의 입력값을 받아야 하는 상황에서 입력값이 포함되어 있지 않은 엔터도 한줄로 인식하기 때문에, 그런 상황을 피하려고 scanner.skip을 하는 것 같다.

 

참고

위키백과 - 새줄문자

stackoverflow - Is a java scanner's nextLine function guaranteed to delimit only on newline characters?

'공부' 카테고리의 다른 글

1장, 2장  (0) 2019.10.26
JVM  (3) 2019.04.07
객체지향 생활 체조  (0) 2019.02.26
AssertJ, JUnitSoftAssertions  (0) 2019.01.18
접근 제어자  (0) 2019.01.17