본문 바로가기

JAVA/Study

[JAVA] nextline 오류 원인과 해법

▒ 문제점 & 원인

public class Main {
public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	
	String a1 = sc.next();
	String a2 = sc.next();
	String b = sc.nextLine();
	
	System.out.println("첫 번째 입력 : " + a1); // 입력값 출력
	System.out.println("첫 번째 입력 : " + a2); // 입력값 출력
	System.out.println("두 번째 입력 : " + b); // 아무것도 출력되지 않음
}
}

 위 예시 사진과 같이 Scanner 클래스 중 next() 계열의 메소드와 nextLine() 메소드를 혼용해서 사용 할 경우 오류 혹은 동작하지 않는 현상이 발생한다. 이는 next()계열의 메소드가 개행문자(\n, \t)를 기준으로 입력을 구분하는 반면, nextLine()메소드는 개행문자를 모두 포함하여 입력을 받기 때문이다.

 

가령, 위 코드의 콘솔 창에서

123 +  [Enter키(1)]  => a1 객체에 123 입력
321 + [Enter키(2)]  => a2 객체에 321 입력

를 입력하는 경우와

123  + [Spacebar키(1)] + 321 + [Enter키(2)]  => a1 객체에는 123이, a2 객체에는 321이 각각 입력

를 입력하는 경우의 결과값은 같다. 상기한 바와 같이 next()계열의 메소드들이 개행문자를 기준으로 입력값을 구분하기 때문인데, 문제는 여기서 발생하게 된다. 위 예시에서 321을 타이핑 한 뒤 입력하는 [Enter키(2)]가 가상의 저장공간에 남아있다가 뒤의 nextLine()에 흡수되는 것이다. 때문에 뒤의 nextLine()메소드가 작동하지 않게되고, nextLine()에의 입력값을 필요로 하는 다른 기능에까지 연쇄적으로 영향을 미치면서 오류가 발생하게 되는 것이다.

 

 

▒ 해결방법 두 가지

첫 번째 해결 방법

public class Main {
public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	
	String a = sc.next();
	String b1 = sc.nextLine(); // 개행문자 흡수용
	String b2 = sc.nextLine();
	
	System.out.println("첫 번째 입력 : " + a); // 입력값 출력
	System.out.println("두 번째 입력 : " + b1); // enter를 입력받아 생략됨
	System.out.println("두 번째 입력 : " + b2); // 입력값 출력
}
}

가장 간단한 방법은, 사용하고자 하는 nextLine()메소드 위에 nextLine() 을 한 번 더 넣어주어 개행문자를 흡수하도록 하는 방법이다. 가장 기본적인 방법이다.

두 번째 해결 방법

public class Main {
public static void main(String[] args) {
	Scanner sc1 = new Scanner(System.in);
	Scanner sc2 = new Scanner(System.in);
	
	String a = sc1.next();
	String b2 = sc2.nextLine();
	
	System.out.println("첫 번째 입력 : " + a); // 입력값 출력
	System.out.println("두 번째 입력 : " + b2); // 입력값 출력
}
}

두 번째 방법은, Scanner 객체를 구분하여 사용하는 방법이다. Scanner 객체가 분리된다면 상호간에 개행문자로 인한 간섭이 발생하지 않는다.

 

그 외

간혹 try/catch 예외처리문에서 catch문이 무한 반복되는 현상이 발생하는 경우도 이와 원인이 같으므로 같은 방법으로 해결 할 수 있다.