본문 바로가기
코테/백준(Java)

Scanner 클래스와 입력[InputStream,BufferedReader]

by Wanado 2022. 8. 23.
728x90

출처: https://st-lab.tistory.com/92

 

기본적인 데이터 타입들을 Scanner 의 메소드를 사용하여 입력받을 수 있다.

예로 들어 100을 입력하고자 할 때,

String(문자열)로 입력받고 싶으면 next() 나 nextLine() 을,

int(정수)로 입력받고 싶다면 nextInt() 를 사용하여 입력받으면 알아서 해당 타입으로 입력된다.

 

공백(띄어쓰기) 또는 개행(줄 바꿈)을 기준으로 읽는다.

 


Scanner in = new Scanner(System.in); // Scanner 객체 생성

주의할 것은 Scanner 을 생성할 때 System.in 이 들어간다는 점이다.

System.in 은 사용자로부터 입력을 받기 위한 입력 스트림이다.

 

자바에서 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 형 입력 및 리턴 (개행을 기준으로 한 줄을 읽음)
  • next() 와 nextLine() 의 차이

여러분들이 문자열을 입력받을 때 가장 주의해야 할 메소드다.

일단 next() 는 '한 단어' 그러니까 공백을 기준으로 문장 한 개만 읽어 들인다.

nextLine() 은 위와 반대로 '한 줄' 즉, 한 줄에 입력된 여러 문장들을 읽는다.

 


출처: https://st-lab.tistory.com/41

 

  • System.in 그리고 InputStream

자바에서 가장 기본이 되는 입력 스트림은 InputStream 이다.

(반대로 출력 스트림은 OutputStream 이다.)

 

 System.in은  InputStream 타입의 필드이다.

 System 클래스의 in 이라는 필드는 InputStream 의 정적 필드.

System 클래스 in 변수는 '표준 입력 스트림'이며 일반적으로 콘솔, 명령줄 인수 등을 통해 입력을 받을 수 있다. 매우 간략하게 말하자면 여러분이 키보드로 치거나 터미널 등에서 입력을 넣어주는 것들은 System.in 을 통해 연결된다는 의미다.

정리하자면 in 이라는 변수는 InputStream의 변수로 결국 InputStream 타입의 새 변수를 선언하고 그 변수에 System.in 을 할당시킬 수도 있다는 뜻이다.

public static void main(String[] args) throws IOException {
InputStream inputstream = System.in;
int a = inputstream.read();   해당문자의 시스템 또는 운영체제의 인코딩 형식의 10진수로 변수에 저장
                                             1byte만 읽는다. 따라서 2Byte문자를 쓰려면 두번 작성해주어야함.
System.out.println(a);
}

만약 10개의 문자를 입력받고 싶으면 10개의 변수를 선언해야 해??

물론 그럴 수도 있지만 다행히도 바이트 타입 배열을 선언하고 read() 메소드에 넣어서 입력받는 방법도 있다.

문자로 치환하고 싶으면 char 으로 캐스팅을 해주어야 하고,  무엇보다 한글을 제대로 인식하지 못한다.

 

inputStreamReader

 InputStream 의 바이트 단위로 읽어 들이는 형식을 문자단위(character)로 데이터로 변환시키는 중개자 역할을 한다고 보면 좋다.  이러한 InputStreamReader  문자스트림이라고 한다.

더보기

public class Input_Test {
public static void main(String[] args) throws IOException {

InputStream inputstream = System.in;
InputStreamReader sr = new InputStreamReader(inputstream);

int c = sr.read();

System.out.println((char)c);
System.out.println(c);

}
}

 InputStreamReader 의 가장 큰 특징은 다음과 같다.

  1. 바이트 단위 데이터를 문자(character) 단위 데이터로 처리할 수 있도록 변환해준다.
  2. char 배열로 데이터를 받을 수 있다.

여기까지 과정을 이해했다면 아마 BufferedReader 에 대한 이야기 또한 금방 이해될 것이다.

BufferedReader 객체를 생성, 선언을 할 때 보통 우리는 다음과 같이 쓴다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

 

위 코드를 풀어쓰면 다음과 같을 것이다.

 
InputStream inputstream = System.in;
 
InputStreamReader sr = new InputStreamReader(inputstream);
 
BufferedReader br = new BufferedReader(sr);

근데 BufferedReader 는 왜 필요해??

이 질문에 대한 답이 필요하다.

 

앞서 Scanner 에서 InputStreamReader 을 설명할 때 '문자'를 처리한다고 했다. '문자열'이 아니다.

그래서 쓰는 것이 Buffer(버퍼)를 통해 입력받은 문자를 쌓아둔 뒤 한 번에 문자열처럼 보내버리는 것이다.

 

BufferedReader 를 쓸 때 우리는 입력 메소드로 readLine() 을 많이 쓴다. 이 메소드는 한 줄 전체를(공백 포함) 읽기 때문에 char 배열을 하나하나 생성할 필요 없이 String 으로 리턴하여 바로 받을 수 있다는 장점이 있다.

 

BufferedReader 의 특징은 크게 두 가지가 있다.

  1. 버퍼가 있는 스트림이다.
  2. 별다른 정규식을 검사하지 않는다.

 

위와 같이 두 개의 특징 덕분에 입력 과정에서 Scanner에 비해 성능이 우수할 수밖에 없다.

그리고 BufferedReader 의 경우 Scanner 와 다르게 문자열 그대로 읽어 들이기 때문에 별다른 정규식을 검사하지 않는다.

그렇기 때문에 Scanner 에 비해 성능이 좋을 수밖에 없다는 것.

즉, 정리하자면 바이트 단위 [InputStream]로 문자를 입력받아 문자(character) [InputStreamReader]로 처리한 뒤 버퍼(buffer) [BufferedReader]에 담아두었다가 일정 조건이 되면 버퍼를 비우면서 데이터를 보내는 것이다.

 


  1. InputStream 은 바이트 단위로 데이터를 처리한다. 또한 System.in 의 타입도 InputStream 이다.
  2. InputStreamReader 은 문자(character) 단위로 데이터를 처리할 수 있도록 돕는다. InputStream 의 데이터를 문자로 변환하는 중개 역할을 한다.
  3. BufferedReader 은 스트림에 버퍼를 두어 문자를 버퍼에 일정 정도 저장해둔 뒤 한 번에 보낸다.
728x90

'코테 > 백준(Java)' 카테고리의 다른 글

9498 시험점수  (0) 2022.08.23
10926 ??! (예외클래스)  (0) 2022.08.19
1008 A/B 부동소수점  (0) 2022.08.19
1000 A+B  (0) 2022.08.19