자바 표준 입력 스캐너(Scanner) 클래스의 사용 방법과 주의할 점
✓ Scanner Class란?
자바의 입력 방식 중에 가장 대중적인 것이 자바 기존 입력 클래스인 스캐너(Scanner) 이다.
기본적인 데이터 타입(정수, 실수, 문자열 등)을 Scanner 클래스를 사용하여 입력받을 수 있다.
Scanner를 사용하기 위해서 util 패키지에 있는 Scanner 클래스를 import 해야한다.
또한, 입력 메소드 대부분은 공백과 개행(' ', '\n, \t, \r 등')을 기준으로 읽어 들인다. 공백과 개행을 기준으로 구분되는 요소를 토큰(token)
이라고 한다. Scanner 클래스는 입력 값을 대부분 토큰 단위로 읽고(nextLine()은 Enter 단위로 읽음), 이 토큰을 반환하는 데이터 형태에 따라 몇가지 메서드가 Scanner 클래스에 존재한다.
✓ Scanner 메서드
메서드 | 설명 |
---|---|
String next() | 다음 토큰을 String으로 반환. 띄어쓰기 뒷부분은 읽지 않음. |
int nextInt() | 다음 토큰을 int로 반환. |
String nextLine() | '\n'(줄 바꿈)을 포함하는 한 줄을 읽고 \n을 제외한 나머지 문자열을 반환. |
boolean nextBoolean() | 다음 토큰을 boolean으로 반환 |
byte nextByte() | 다음 토큰을 byte로 반환 |
short nextShort() | 다음 토큰을 Short로 반환 |
long nextlong() | 다음 토큰을 long로 반환 |
float nextFloat() | 다음 토큰을 Float로 반환 |
double nextDouble() | 다음 토큰을 double로 반환 |
boolean hasNext() | 현재 입력된 토큰이 있으면 true, 아니면 무한 대기 상태, 그러다 입력이 들어오면 true, ctrl z가 입력되면 false를 반환 |
void close() | 생성한 Scanner객체를 닫는다.(사용종료 한다.) |
✓ Scanner 사용
java.util 패키지에 포함되어 있는 외부 클래스 Scanner 호출
x
import java.util.Scanner ;
Scanner 객체 생성
Scanner sc = new Scanner(System.in) ;
System.in : 입력한 값을 바이트 단위로 읽음
적용
import java.util.Scanner;
public class Main {
public static void masc(String[] args) {
Scanner sc = new Scanner(System.in) ;
String h = sc.next();
int c = sc.nextInt();
String i = sc.nextLine();
boolean g = sc.nextBoolean();
byte a = sc.nextByte();
short b = sc.nextShort();
long d = sc.nextLong();
float e = sc.nextFloat();
double f = sc.nextDouble();
}
}
✓ 공백과 개행(' ', '\n, \t, \r 등')문자도 함께 저장!
컴퓨터는 입력을 받을 때 ' ', '\n, \t, \r 등의 문자도 함께 버퍼에 저장된다. 그래서 다음 문자를 읽어들이기 전까지 다음 ' ', '\n, \t, \r 등의 문자들은 버퍼에 남아있다.
❕ Scanner 클래스 사용 시 주의해야 할 점 ❕
그래서 각 메서드의 특징에 따라 주의하며 사용해야 한다.
next()와 nextline()
next()는 띄어쓰기 전까지의 토큰을 가져오고 nextLine의 경우에는 \n까지 모든 라인을 가져온다.
xxxxxxxxxx
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in) ;
System.out.println("a 입력");
String a = sc.next();
System.out.println("b 입력");
String b = sc.nextLine();
System.out.println("a : " + a + ", b : " + b);
}
}
'안녕 하'라고 입력하고 엔터(\n)를 입력했을 경우 next() 메서드를 사용하여 선언된 변수 a에는 '안녕'까지 저장되었고 다음 nextLine() 메서드를 사용하여 선언된 변수 b는 입력받지 않았음에도 띄어쓰기가 포함된 ' 하' 라는 문자가 저장된 것이다.
nextInt()와 nextLine()를 함께 사용한 예시를 통하여 nextLine()의 특징에 대해서 더 알아보자
nextInt()와 nextLine()
xxxxxxxxxx
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in) ;
System.out.println("a 입력");
int a = sc.nextInt();
System.out.println("b 입력");
String b = sc.nextLine();
System.out.println("a : " + a + ", b : " + b);
}
}
이번 예제를 보면 a라는 변수를 선언하기 위하여 nextInt()를 사용했다. 32를 입력하여 Enter(\n)를 입력했고 b변수를 선언하기 위해 nextLine()으로 값을 입력 받으려고 했으나 입력 받기 전에 main 함수 실행이 종료되었다.
nextInt() 메서드는 공백문자(이 예제에서는 Enter)를 제외해서 읽어서 32라는 숫자만 읽어들인다. 그러면 입력 버퍼에는 nextInt()가 읽지 않은 \n(Enter)만 남게 되고, nextLine() 메서드는 \n까지만 읽어들이므로 입력 버퍼에 저장되어 있는 \n까지 읽는 것이다.
그래서 다음 값을 입력하기 전에 입력이 끝나게 되는 것이다. 또한, nextLine()의 경우에 반환 시에는 \n을 제외한 값이 반환되므로 아무 값도 반환되지 않음을 확인할 수 있다.
❔ 위의 문제 해결 방법
nextLine() 메서드가 \n 버퍼에 저장된 공백문자를 읽어들이고 \n 값을 제외하여 반환하는 특성을 이용하여 nextLine()을 한 번 더 사용하여 입력 버퍼에 있는 \n를 버려주어 다시 string을 입력받으면 된다.
xxxxxxxxxx
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in) ;
System.out.println("a 입력");
String a = sc.next();
sc.nextLine(); // 입력 버퍼에 남아있는 \n을 버리기 위하여 사용
System.out.println("b 입력");
String b = sc.nextLine();
System.out.println("a : " + a + ", b : " + b);
}
}
즉, nextLine()과 다른 메서드의 차이점을 정리하면,
✓ nextLine()과 다른 메서드의 차이점
- 다른 메서드들은 토큰(Token) 단위로 읽고, nextLine()은 Enter(\n) 단위로 읽는다.
- 다른 메서드들은 ' ', '\n, \t, \r 등의 공백문자를 제외해서 읽어들이고, nextLine()은 \n을 포함하여 읽고 반환 시 \n을 제외하여 반환한다.