티스토리 뷰
APS를 풀 때 가장 간단한게 사용할 수 있는 입출력 메서드는, Java의 System 클래스에서 제공하는 메서드들이다.
출력 : System.out
System.out 은 System 클래스에서 제공하는 정적 필드로, PrintStream 타입의 Java 표준 출력 스트림이다.
여기서 스트림이나 PrintStream 이 무엇인지 하나하나 설명할 수는 없으니, 그냥 "출력"에 관여하는 가장 기본적인 클래스라고 생각하면 된다. System.out에서 가장 중요한 메서드는 print() 로, 문자열을 콘솔창에 출력한다.
| System.out.println() | 입력받은 인수를 모두 출력하고 개행한다. |
| System.out.print() | 입력받은 인수를 모두 출력하고 개행하지 않는다. |
| System.out.printf() | 입력받은 문자열 템플릿(서식)을 사용하여 출력할 수 있다. |
printf에 대한 설명은 Java 이론에서 배우도록 하고, APS에서는 보통 System.out.println() 메서드를 많이 사용하게 된다.
대부분의 APS 문제들은 입력값에 비해 출력값은 단순한 편이며, 그렇지 않은 경우에도 대용량이 아니면 유의미한 속도차이가 나지 않는다. (차라리 StringBuilder 등으로 출력값을 모아서 출력하는 것과 같은 테크닉이 더 중요하다.)
게다가 또한 입력받는 자료형이 중요해서 온갖 파싱을 해야하는 입력과는 달리, print 시리즈는 인수를 어떤 자료형으로 넣어도 알아서 호출해서 문자열로(단, 객체는 toString() 메서드가 없으면 주소값 그대로 출력) 바꿔주기 때문에 크게 신경 쓸 거리도 없다.
입력 : System.in
System.in 은 System 클래스에서 제공하는 정적 필드로, InputStream 타입의 Java 표준 입력 스트림이다.
위와 같이 간단하게 "입력"에 관여하는 가장 기본적인 클래스라고 생각하면 된다. System.in에서 가장 중요한 메서드는 read() 로, 바이트를 기반으로 데이터를 읽는다.
| System.in.read() | 입력된 값 중 1바이트 만큼을 읽어 반환한다. |
| System.in.read(byte[] b) | 입력된 값을 빈 배열의 크기만큼 받아 읽은 바이트 수를 반환한다. |
System.in.read()는 Java의 모든 입력법의 근간이 된다. OS의 기본 입출력시스템인 stdin 과 연동되어있기 때문에, 앞으로 설명할 다양한 입력법(Scanner, BufferedReader 등) 역시 이 메서드를 골자로 구현되어 있다.
System.in.read()는 입력된 값의 1 바이트만큼 읽어 int형으로 반환한다. ASCII 나 UTF-8 인코딩 방식이 최소 1바이트로 표현되기 때문이다.한번 읽은 데이터는 없어지므로 다시 메서드를 호출하면 그다음 글자를 읽어오며, 입력값이 끝났을 경우(EOF) -1을 반환한다. 아래의 예를 살펴보도록 하자.
public class Main {
public static void main(String[] args) throws IOException {
System.out.println("입력값:");
int data = System.in.read();
System.out.println("출력값:");
System.out.println(data);
while((data = System.in.read()) != -1){
System.out.println(data);
}
}
}
결과

1바이트씩 읽기 때문에 일단 ASCII 코드 범위 (알파벳 대소문자, 숫자, 간단한 기호 등)는 간편하게 읽을 수 있지만, 사실 APS에서 사용하기에는 애로사항이 꽃핀다. 일단 위의 예제에서 보이듯 뜬금없이 10이 등장하는데, 하나씩 읽다보니 엔터(ASCII 코드로 10)키도 읽어버린 것이다. 읽은 데이터를 int 혹은 byte[] 값으로 저장하기 때문에, 받은 데이터를 그대로 쓸 수도 없다. 아래의 예시를 보자.
public class Main {
public static void main(String[] args) throws IOException {
System.out.println("숫자 입력값:");
int data = System.in.read();
System.out.println("출력값:" + (data-48)); // 0의 ASCII코드가 48이므로
System.in.read(); // 엔터 제거
System.out.println("문자 입력값:");
data = System.in.read();
System.out.println("출력값:" + (char)data); // 형변환
System.in.read(); // 엔터 제거
System.out.println("문자열 입력값:");
byte[] arr = new byte[100];
int length = System.in.read(arr);
System.out.println("출력값:" + new String(arr,0,length));
}
}
결과

간단한 숫자와 문자값이야 변환하기 간단하고, 문자열은 String 생성자를 사용해서 byte 배열 그대로 문자열로 바꿔버리는 방법이 있긴 하다. 다만 APS는 일반적으로 숫자 입력값이 많은데, 두자리 수를 넘어가는 숫자는 저런 방식으로 입력을 받을수가 없다. 하나하나 읽어서 자릿수 처리하는 메서드를 만들래야 못만들 것도 없지만 1분 1초가 급한 APS (코딩테스트, 대회)등에선 사용하기 힘들다.
다만 백준과 같은 사이트에서 실행 속도를 올리는 용도로 코드를 짜본다면 System.in.read()를 그대로 사용하는게 의미가 있을 수 있다. 나중에 설명하겠지만, Scanner나 BufferedReader가 아무리 빠르다해도 편의성이나 범용성을 위해 여러가지 오버헤드를 가지는 반면, System.in.read()는 숫자 하나하나를 읽어오기만 할 뿐이다.
숫자 구분(공백)은 read() 메서드의 반환값으로 처리가 가능하며, 자리수 처리는 연산자들을 통해서 처리가능하다. 아래 예제를 보자.
public static int read() throws Exception{
int n = 0; // 읽어온 숫자
int cur; // 현재 숫자
boolean isNumber = false; // 숫자인지 아닌지
while(true){
cur = System.in.read(); // 읽어옴
if(cur <= 32){ // 스페이스 등의 구분자라면
if(isNumber){ // 만약 숫자라면 이제 더이상 숫자가 아니므로
return n; // n 을 반환
}
// 숫자가 아니라면 어차피 구분자의 연속이니 무시하고 넘어감
}
else{ // 구분자가 아니라면
isNumber = true; // 어쨌든 숫자가 시작했으니
n = n*10 + (cur-48); // 자릿수 변경
}
}
}
이 메서드는 공백기호를 구분자로 둔 숫자를 읽어내는 메서드다. 물론 System.in.read()를 과도하게 많이 호출해야 하기 때문에 입력받는 숫자가 많아질수록 느려질 수 있고, 고자릿수 숫자가 들어오면 자릿수 변경에 드는 오버헤드가 커어디까지나 예시일 뿐이니, 비트마스킹과 버퍼등을 고려해서 자기 나름의 fast I/O 메서드를 만들어 보도록 하자.
'APS > 이론' 카테고리의 다른 글
| [APS] 02 : 자료구조 - 배열 (0) | 2025.03.19 |
|---|---|
| [APS] 01 : 자료구조 개론 (0) | 2025.03.19 |
| 투포인터 - 1 (0) | 2025.02.17 |
| [APS] 입출력 : Buffered 시리즈 (6) | 2024.12.29 |
| [APS] 입출력 : Scanner / StringBuilder (11) | 2024.12.28 |
- Total
- Today
- Yesterday
- DBMS
- BufferedReader
- APS
- 테이블
- oracle
- SQL이란
- 배열
- 레코드
- db오브젝트
- 알고리즘
- DB
- 자료구조
- 입출력
- db의 역사
- BufferedWriter
- dialect
- StringBuilder
- Scanner
- Java
- 데이터베이스
- SQL
- 필드
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |