[자바]콘솔 입출력
콘솔 입력
자바 코드에서 입력한 문자열을 얻기위해서는 자바의 System.in
을 사용한다
1
2
3
4
5
6
7
8
9
10
11
12
13
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
int a;
a = in.read();
System.out.println(a);
}
}
InputStream
은 자바의 내장 클래스이다. 자바의 내장 클래스중에 java.lang
패키지에 속해 있지 않은 클래스는 위 코드처럼 필요할 때 항상 improt 해서 사용해야한다.
System이나 String 등의 클래스는 java.lang
패키지에 속해 있는 클래스이므로 별도의 import 과정이 필요없다
System.in
은 InputStram
의 객체 이다. System.in
을 사용하게 되면 콘솔창에서 입력 값을 받을 수 있다.
InputStream
에는 1byte의 사용자 입력값을 읽을 수 있는 read
라는 메소드가 있다. read 메소드로 읽은 데이터는 byte자료형으로 저장되는 것이 아니라 int 자료형으로 저장된다. 만약 a를 입력했다면 a에 해당되는 아스키코드값인 97이 출력되게 된다.
🙋그렇다면 만약 한글자가 아닌 abc를 입력하면 어떻게 될까?
이번에도 마찬가지로 97이 출력되게 된다. 그이유는 InputStream의 read 메소드는 1 byte만 읽기 때문이다. 즉, 사용자는 “abc”라는 3 byte의 데이터를 전달했지만 프로그램에서는 처음 1 byte만 읽게 된다. 이렇게 입력된 데이터를 입력 스트림(Stram)이라고 한다. 스트림은 이어져 있는 데이터(byte)의 형태를 의미한다.
🤷그렇다면 사용자가 3byte를 입력했을 때 3 byte를 전부 읽고싶다면 어떻게 해야할까?
길이 3짜리 byte 배열을 만든후 read 메소드 입력값으로 전달하면 콘솔 입력이 해당 배열에 저장이 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
byte[] a = new byte[3];
in.read(a);
System.out.println(a[0]);
System.out.println(a[1]);
System.out.println(a[2]);
}
}
1
2
3
4
abc (입력)
97 (출력)
98 (출력)
99 (출력)
👉번외로 여기서 아무런 입력값도 입력하지 않고 엔터를 누르게되면 0이 3번 출력될거 같은데
1
2
3
4
13 (출력)
10 (출력)
0 (출력)
예상했던것과 달리 위와 같이 출력된다. 그 이유는 개행문자, 즉 컴퓨터에서 줄바꿈을 나타내는 제어 문자때문에 일어난일이다. Java에서 줄바꿈을 인식하는 문자 \n
와 커서의 위치를 맨앞으로 옮기는 \r
이 합쳐져서 이둘의 아스키 코드 값이 출력되게 된것이다.
InputStreamReader
하지만 읽어들인 값을 항상 아스키코드 값으로 해석해야 하는 방식은 여전히 불편하다.
🙋♂️입력한 문자값을 그대로 출력해 볼 수 없을까?
바이트 대신 문자로 입력 스트림을 읽으려면 InputStreamReader
를 사용하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
InputStreamReader reader = new InputStreamReader(in);
char[] a = new char[3];
reader.read(a); //char의 배열은 String과 같다
System.out.println(a);
}
}
InputStreamReader를 사용하기 위해 import 문이 하나 더 추가되었다. 그리고 InputStreamReader 객체를 생성할 때는 다음과 같이 생성자의 입력으로 InputStream 객체인 System.in이 필요하다.
1
InputStreamReader reader = new InputStreamReader(System.in);
이전에는 읽어들일 값을 byte배열로 선언했는데 InputStreamReader를 이용하면 다음처럼 byte 대신 char 배열을 사용할 수 있다.
🙋♂️그냥 char로 형변환을 사용하면 되지 굳이 InputStreamReader가 필요할까?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package Test;
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
byte[] a = new byte[3];
in.read(a);
char[] b = new char[3];
for(int i=0; b.length >i; i++) {
b[i] = (char)a[i];
}
System.out.println(b);
}
}
1
2
abc (입력)
abc (출력)
원했던 결과 대로 잘 출력 되는 것을 볼 수 있다 하지만 한글을 사용하게된다면
1
2
안녕 (입력)
??? (출력)
한글이 깨지게된다. 그 이유는 맨처음 말했던거 처럼 InputStram은 1byte씩 사용자 입력값을 읽게되는데 한글은 2byte가 묶여서 한글자가 되기 때문에 한글대신 ?가 출력되게 된것이다. InputStreamReader
는 이러한 문제점을 해결해 준다.
BufferedReader
프로그램이 많이 개선되었지만 여전히 고정된 길이로만 스트림을 읽게 된다.
🤷♂️반복문을 사용하지않고 사용자가 엔터키를 입력할 때까지 사용자의 입력을 전부 받아들일 수 없을까?
BufferedReader
를 이용하면 가능하다!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
String a = br.readLine();
System.out.println(a);
}
}
BufferedReader는 객체 생성시 생성자의 입력값으로 InputStreamReader의 객체가 필요하다. BufferedReader의 readLine메소드를 이용하면 사용자가 엔터키를 입력할 때까지 입력했던 모든 문자열을 읽을 수 있다.
1
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- 한줄로 표현이 가능하다
총정리
- InputStream - byte
- InputStreamReader - character
- BufferedReader - String
Scanner
J2SE 5.0 부터 Scanner 라는 java.util.Scanner
클래스가 새로 추가되었다. Scanner 클래스를 이용하면 콘솔입력을 훨씬 쉽게 사용할 수 있다.
1
2
3
4
5
6
7
8
import java.util.Scanner;
public class Sample {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(sc.next());
}
}
- Scanner를 사용하기 위해서 먼저 java.util.Scanner 클래스를 import 해야한다.
Scanner 클래스는 생성자의 입력으로 System.in
을 필요로 한다.
Scanner 객체의 next()
메소드는 단어 하나를 읽어들인다. 문자열을 읽어 들일려면 nextLine 숫자를 읽어 들일려면 nextInt를 사용하면된다.
총정리
- next - 단어
- nextLine - 라인
- nextInt - 정수
콘솔 출력
지금까지 System.out.println
메서드를 계속해서 사용해 왔다. System.out
은 PrintStream 클래스의 객체이다. 동일한 역할을 하는 객체로 System.err
도 있다. 다만 System.err
는 오류 메시지를 출력할 경우 사용된다.