자바/자바

[Java] System.in으로 데이터 입력받기

도트7 2021. 11. 30. 18:30

 코딩 문제 사이트에서 문제를 풀다가 이 클래스에 대해 알게 되었다. 단계별로 준비된 문제를 풀다가 입출력 문제를 풀게 되었는데 내 코드의 실행 시간과 상위권 유저의 실행 시간이 너무나도 크게 차이났다. 도대체 뭐가 얼마나 차이나는 것인지 궁금해서 공개된 코드를 보게 되었는데 나는 학교에서 배운대로 Scanner를 사용한 반면 상위권 유저들은 모두 System.in으로 입력을 받고 있었다. 출력 시간을 줄이는 노력은 해본적 있지만 입력 시간을 줄인다는 것은 생각해본 적 없었기에 이 클래스가 궁금해졌다.

 

System.in

 System.in은 자바에서 데이터를 입력받는 표준 클래스지만 일반적인 상황에서는 단독으로 사용할 일이 잘 없다. 자바에서 입력을 받아야 하는 상황이라면 대부분 Scanner 혹은 BufferedReader를 사용하기 때문인데 그 이유는 단순히 System.in 클래스를 사용하는 것보다 다른 두 클래스가 사용하기 편하기 때문이다.

 

System.in.read(byte)

 System.in을 사용할 경우 가장 많이 사용되는 메서드로 1byte 크기의 데이터 하나를 입력받을 수 있다. 바꿔 말하면 영문 대소문자, 숫자, 특수문자 등을 입력받을 수 있고 한글은 입력받을 수 없다. 

 

int c = System.in.read();
System.out.println(c);

ex) [ 숫자(문자) 0~9 : 48~57, 대문자 A~Z : 65~90, 소문자 a~z : 97~122 ]

 

 read 메서드는 위와 같이 사용할 수 있다. 위 코드를 실행해서 문자를 입력받으면 어떤 값(숫자, 영문자 등)을 입력해도 정수형으로 반환되는데 이를 이해하려면 아스키 코드를 알아야 한다. 콘솔에서 입력한 값은 아스키 코드표에 해당하는 값으로 저장되기 때문이다. 숫자 0을 입력했다면 변수 c에 48이, 문자 'a'를 입력했다면 97이 초기화될 것이다.

 

 Scanner를 사용하면 숫자, 문자, 문자열 등 원하는 값을 즉시 입력받을 수 있는 메서드들이 존재하지만 System.in을 사용하면 이 메서드 하나로 숫자, 문자를 모두 입력받아야 한다. 이 메서드 자체로는 아스키 코드값밖에 얻을 수 없으니 숫자나 문자를 저장하고 싶으면 그에 맞는 가공 작업이 필요하다.

 

 

문자로 입력받기

char c = (char)System.in.read();
System.out.println(c);

 입력받은 문자를 그대로 출력하기 위한 방법 중 하나는 형 변환(Type Casting)이다. 입력을 받을 때 강제로 형 변환을 시키면 아스키 코드값에 맞는 문자가 변수에 초기화된다.

 

 

숫자로 입력받기

int num = System.in.read() - 48;
System.out.println(num);

 숫자 0을 입력받았다고 가정할 때 숫자 0은 아스키 코드표에서 48에 해당하기 때문에 num에는 48이 저장된다. 이 값을 숫자로 사용하려면 입력받은 값에 -48 연산을 해주면 된다.

 

 

10이상의 수 입력받기

int num = System.in.read();
System.out.println(num);

 위 코드를 실행하고 "12"를 입력하면 "49"가 출력된다. 앞서 말한 것처럼 read()는 1바이트 단위로 입력을 받기 때문에 입력한 값 중 먼저 입력한 '1'의 아스키 코드값인 49만 저장된 것이다.

 

 

public class Main {
	public static void main(String args[]) throws Exception {
		int num = readInt();
		System.out.println(num);
	}
	
	public static int readInt() throws Exception {
		InputStream is = System.in;
		int sum = 0;
		
		while(true) {
			int n = is.read();
			
			if(n == '\n')
				return sum;
			else if (n >= 48 && n <= 57)
				sum = (sum*10) + (n-48);
		}
	}
}

 두 자리 이상의 수를 저장하려면 키보드에서 입력이 들어올때 마다 입력된 값이 숫자인지를 판별하여 값을 누적시켜야 한다. 입력되는 수가 늘어날수록 자릿수가 하나씩 증가하기 때문에 누적된 값에 *10을 하고 입력되는 값을 더해주는 것으로 10 이상의 숫자를 입력받을 수 있다.

 

 


 

 

 System.in은 Scanner, BufferedReader와 비교하면 입력하는 값에 따라 그에 맞는 구현을 해줘야한다는 것, 입력에서 발생할 수 있는 예외를 처리해줘야 한다는 단점이 있다. 이런 이유로 System.in으로 입력받는 방법을 알게 된 후에도 코딩 문제를 풀 때를 제외하면 사용할 일이 크게 없는 것 같다.