자바 [JAVA] - 스캐너(Scanner) 클래스와 입력
자바를 처음 배울 때 아마 대부분은 키보드로 입력받기 위해 Scanner 라는 클래스를 썼을 것이다.
자바 외에도 다양한 언어들은 각각의 입력방식이 있고, 각 언어별로 대표하는 대중적인 입력방식이 하나씩 있다.
예로 들면 C언어의 경우 scanf() 가 있을 것이고 파이썬의 경우 input(), C++ 은 cin, C# 은 Console.readLine() 등이 있다.
자바에서도 여러가지 입력방법이 입력방법이 있는데, 그중 가장 쉬우면서도 대중적인 입력 중 대표적인 것이 바로 Scanner 클래스를 이용한 입력이다.
이번 포스팅에서는 Scanner 의 사용 방법에 대해 자세하게 알아보자.
-
Scanner 클래스의 특징
- 기본적인 데이터 타입들을 Scanner 의 메소드를 사용하여 입력받을 수 있다.
예로 들어 100을 입력하고자 할 때, String(문자열)로 입력받고 싶으면 next() 나 nextLine() 을, int(정수)로 입력받고 싶다면 nextInt() 를 사용하여 입력받으면 알아서 해당 타입으로 입력된다. - Scanner 을 사용할 시 util 패키지를 경로의 Scanner 클래스를 호출해야 한다.
자바에서 쓰이는 대부분의 클래스는 lang 패키지가 아니라면 import 을 통해 호출해주어야 한다.
Scanner 의 경우는 java.util 패키지에 있다. - 공백(띄어쓰기) 또는 개행(줄 바꿈)을 기준으로 읽는다.
Scanner 의 입력 메소드들은 대부분 공백과 개행(' ', '\t', '\r', '\n' 등등..)을 기준으로 읽는다. 이 덕분에 사용자의 편의에 따라 쉽게 입력을 받을 수 있다.
- Scanner 사용해보기
Step 1. import 문
앞서 Scanner 의 특징에서 언급했듯이 Scanner 클래스를 사용하기 위해서는 호출해주어야 한다고 했다.
자바의 경우 java.util 패키지 안에 Scanner 클래스가 있으므로 다음과 같이 import 를 쓴 후 해당 클래스 경로를 호출하도록 한다.
import java.util.Scanner; // Scanner 클래스 호출
Step 2. Scanner 객체 생성
우리가 입력을 하기 위해 Scanner 클래스를 쓰고자 먼저 클래스를 호출했다.
그다음으로 해야 할 것이 바로 객체 생성이다.
기본적으로 객체 생성하는 방법은 다음과 같다.
클래스_이름 객체_이름 = new 클래스_이름();
즉, 우리는 Scanner 라는 클래스를 사용할 것이기 때문에 클래스 이름에는 Scanner 가 들어가야 한다.
객체 이름은 여러분들이 편한 대로 지정하면 된다.
(대체로 Scanner 의 경우 객체이름은 in, input, sc, scan 이렇게 4가지가 가장 많이 쓰인다.)
Scanner 의 경우 아래처럼 객체를 생성해주면 된다.
Scanner in = new Scanner(System.in); // Scanner 객체 생성
주의할 것은 Scanner 을 생성할 때 System.in 이 들어간다는 점이다.
System.in 은 사용자로부터 입력을 받기 위한 입력 스트림이다.
그렇기 때문에 Scanner 뿐만 아니라 다른 입력 방식들도 사용자로부터 입력을 받기 위해서는 System.in 이 들어간다.
만약 막 자바를 접한 분이라면 일단 그렇다는 정도만 이해를 하면 된다.
만약 이에 대해 궁금한 분이라면 아래 포스팅을 참고하길 바란다.
Step 3. 메소드를 이용하여 입력하기
자바에서 Scanner 의 입력 메소드는 다음과 같은 종류들이 있다.
in.nextByte() // byte 형 입력 및 리턴
in.nextShort() // short 형 입력 및 리턴
in.nextInt() // int 형 입력 및 리턴
in.nextLong() // long 형 입력 및 리턴
in.nextFloat() // float 형 입력 및 리턴
in.nextDouble() // double 형 입력 및 리턴
in.nextBoolean() // boolean 형 입력 및 리턴
in.next() // String 형 입력 및 리턴 (공백을 기준으로 한 단어를 읽음)
in.nextLine() // String 형 입력 및 리턴 (개행을 기준으로 한 줄을 읽음)
즉, 실전에 적용해본다면 아래와 같다.
import java.util.Scanner; // Scanner 클래스 호출
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in); // Scanner 객체 생성
byte a = in.nextByte(); // byte 형 입력 및 리턴
short b = in.nextShort(); // short 형 입력 및 리턴
int c = in.nextInt(); // int 형 입력 및 리턴
long d = in.nextLong(); // long 형 입력 및 리턴
float e = in.nextFloat(); // float 형 입력 및 리턴
double f = in.nextDouble(); // double 형 입력 및 리턴
boolean g = in.nextBoolean(); // boolean 형 입력 및 리턴
String h = in.next(); // String 형 입력 및 리턴 (공백을 기준으로 한 단어를 읽음)
String i = in.nextLine(); // String 형 입력 및 리턴 (개행을 기준으로 한 줄을 읽음)
}
}
외울 것이 많아 보이지만 기본적으로 String 입력만 제외하면 규칙이 있다.
next + Type() 의 조합으로 쓰면 된다.
아마 여러분들이 가장 많이 쓰게 될 것은
nextInt()
nextDouble()
next()
nextLine()
이렇게 될 것이다.
(참고로 char 형(문자)타입으로 받는 메소드는 따로 없다. String으로 받은 뒤, charAt() 메소드로 문자로 반환해야한다.)
그 외의 메소드들은 아래를 참고하자.
https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html
- next() 와 nextLine() 의 차이
여러분들이 문자열을 입력받을 때 가장 주의해야 할 메소드다.
일단 next() 는 '한 단어' 그러니까 공백을 기준으로 문장 한 개만 읽어 들인다.
nextLine() 은 위와 반대로 '한 줄' 즉, 한 줄에 입력된 여러 문장들을 읽는다.
예로 들면 아래와 같다.
먼저 next() 를 보자.
보면 알 수 있듯이 한 줄에 "Cat is perfect animal" 이라고 입력했으나, Cat 만 str 에 담겼다.
이렇듯이 next() 의 경우 하나의 문장, 즉 앞서 말했던 공백 또는 줄 바꿈까지만 읽는다.
즉, 4개의 문장을 모두 읽기 위해서는 next() 을 4번 써주어야 한다.
[한 줄로 입력]
[한 문장당 한 개행씩 입력]
반면에 nextLine() 은 다르다.
Line 이라는 말 그대로 한 줄을 읽는다. 즉 한 줄 안에 공백 유무와 상관없이 개행(줄 바꿈)까지 읽는다는 것이다.
이렇듯이 입력을 어떻게 받을 것이냐에 따라 쓰임이 다르다.
이러한 메커니즘 때문에 next 와 nextLine() 을 혼용해서 쓸 경우 조심해서 써야 하는데,
대표적으로 아래와 같은 상황이 있다.
잘 보면 next() 메소드에서 Cat 까지 읽고 다음 nextLine() 에서 나머지 문자열을 읽는데, 출력에서 볼 수 있듯이 두 번째 줄에 공백이 포함되어 나왔다.
이유는 next() 에서 공백을 입력받으면 공백 전 문자까지 읽어 들여 str1 에 저장되고, 공백은 남아있게 된다.
그러고 나서 nextLine() 을 쓰면 남아있던 공백부터 한 줄을 읽기 때문에 str2 에는 공백부터 시작하여 한 줄을 읽어 들인 문자가 담기는 것이다.
이 것이 문제가 되는 것은 다음과 같은 상황 때문이다.
이렇듯이 한 줄씩 입력하면 next 는 개행 또는 공백을 입력받을 때까지만 읽다 보니
Cat 다음 개행이 주어져 st1 에는 "Cat" 이 저장되고 다음 개행에서 "is" 를 읽어 str2 에 저장된다.
그리고 다음 메소드는 nextLine() 이라서 한 줄을 읽는데, 앞선 is 다음에 입력한 개행(엔터)이 남아있던 것이 그대로 nextLine()에서 한 줄까지 읽는다는 메커니즘 때문에 개행이 바로 str3 에 저장되고 다음 입력 줄로 넘어가 버린다.
그래서 next() 와 nextLine() 을 혼용해서 쓸 경우 조심해서 써야 하고
위 케이스처럼 불가피하게 혼용해서 써야 할 경우는 아래와 같이 해야 한다.
next() 다음 nextLine() 입력 사이에 nextLine() 을 추가한다.
즉, 아래 사진과 같이 해야 한다.
위와 같이 하면 정상적으로 입력이 가능하다.
- 마무리 정리
Scanner 에 대한 기본적인 사용 방법들을 알아보았다.
지금 막 자바를 접한 분들이라면 뒷부분의 내용은 조금 어려울 수도 있다.
스트림에 대한 이해가 있어야 하기 때문에 위 메커니즘을 완벽히 이해하기 어려울 것이다.
만약에 스트림에 대해 좀 더 알아보고 싶다면 아래 포스팅을 꼭 읽어보길 바란다.
여러분들에게 많은 도움이 될 것이다.
혹여나 모르거나 어려운 부분이 있다면 언제든 댓글 달아주시면 최대한 빠르게 답변드리도록 하겠다.
'Java' 카테고리의 다른 글
자바 [JAVA] - Comparable 과 Comparator의 이해 (261) | 2021.04.29 |
---|---|
자바 [JAVA] - 제네릭(Generic)의 이해 (112) | 2020.10.19 |
패스워드의 암호화와 저장 - Hash(해시)와 Salt(솔트) (69) | 2020.05.23 |
JAVA [자바] - 입력 뜯어보기 [Scanner, InputStream, BufferedReader] (231) | 2020.02.24 |