-
스트림(Stream)과 자바(Java)의 Scanner 클래스ProgrammingLanguage/Java 2021. 1. 14. 21:22
*입출력 스트림(Stream)
->컴퓨터 공학에서 스트림은 연속적인 데이터의 흐름 혹은 데이터를 전송하는 소프트웨어 모듈을 말한다. 이름의 의미와 마찬가지로 스트림은 도착한 순서대로 데이터를 흘려 보낸다.
->스트림을 통해 흘러가는 데이터의 기본 단위는 바이트(Byte)이다.
->입력 스트림(Input Stream) : 입력 장치(마우스, 키보드, 네트워크...)와 프로그램이 연결되어, 입력된 데이터가 프로그램으로 순서대로 흘러간다.
->출력 스트림(Output Stream) : 프로그램과 출력 장치(모니터, 프린터, 네트워크...)가 연결되어, 출력 데이터가 출력 장치로 순서대로 흘러간다.
※위의 그림을 통해 스트림은 단방향이며, 선입선출(FIFO) 구조임을 알 수 있다.
->자바는 바이트 스트림과 문자 스트림으로 나뉜다. 바이트 스트림은 입출력되는 바이트의 바이너리 값을 있는 그대로 처리하므로 어떤 데이터가 들어와도 처리할 수 있다. 하지만 문자 스트림은 오직 문자만 다룰 수 있다.
->자바의 표준 입출력 : 자바에서는 System 클래스를 이용하여 표준 입력(System.in), 표준 출력(System.out), 표준 에러(System.err)를 제공한다.
*Scanner 클래스
->정규식을 사용하여 기본 데이터 타입/문자열을 구문 분석할 수 있는 간단한 텍스트 스캐너.
※정규식(Regular expression, regex) : 특정한 규칙을 가진 문자열의 집합을 표현하는 형식 언어. 다양한 문자열의 검색과 치환을 위하여 지원된다.
->쉽게 말해 Scanner 클래스는 다양한 타입의 입력 값들을 읽어들이기 위한 편리한 방법을 제공하는 클래스이다.
->Scanner 클래스의 생성자에는 다양한 데이터가 들어갈 수 있다.
import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { // 표준 입력 스트림을 생성자로 Scanner 클래스를 선언한 예. Scanner scan = new Scanner(System.in); int a = scan.nextInt(); String b = scan.next(); System.out.println(a); System.out.println(b); } }
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ScannerTest { public static void main(String[] args) throws FileNotFoundException { // 텍스트 파일을 생성자로 Scanner 클래스를 선언한 예. Scanner scan = new Scanner(new File("./src/practice/myText.txt")); while (scan.hasNext()) { int a = scan.nextInt(); System.out.println(a); } } }
->Scanner은 공백 또는 개행 문자를 기준으로 입력 값들을 읽기 때문에, 사용자의 편의에 따라 쉽게 입력을 받을 수 있는 장점이 존재한다.
※nextLine() 메서드 : Scanner를 이용한 입력에서 특히 주의 해야하는 메서드이다. next(), nextInt() 등의 메서드는 띄어쓰기를 기준으로 입력 값들을 읽고, nextLine() 메서드의 경우 한 라인을 기준으로 입력 값들을 읽는다. 이 경우 문제가 발생할 수 있는데, next() 계열 메서드를 입력한 후 Enter를 입력하는 경우, next()계열 메서드는 Enter의 줄바꿈 문자를 처리하지 못하고 버퍼에 남겨 둔다. 이 남겨둔 개행 문자를 다음 라인에서 nextLine()이 인식하는 순간, 의도치 않은 출력 결과를 볼 수 있게 된다.
import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 이름을 입력하고 Enter를 입력하면, Enter이전의 값들만 name에 입력되고 Enter 값은 버퍼에 남는다. String name = scan.next(); // 버퍼에 남은 Enter값을 바로 인식해버려, grade에는 Enter값이 할당된다. String grade = scan.nextLine(); System.out.println(name); System.out.println(grade); } }
->그림을 참고해보면, grade를 입력하기도 전에 프로그램이 종료된 것을 알 수 있다. 또한, 아래 공백문자가 grade의 값으로 출력된 것을 알 수 있다!(공백 문자를 인식하지 못했다면 아래 공백 부분은 출력되지 않는다). 이는 아래와 같은 두 가지 방법을 이용하여 해결 할 수 있다.
(1) 인위적인 개행 문자 제거
import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int age = scan.nextInt(); // 인위적으로 해당 라인을 삽입하여 개행 문자를 제거한다! scan.nextLine(); String grade = scan.nextLine(); System.out.println(age); System.out.println(grade); } }
(2) Wrapper 클래스 활용
import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 개행 문자까지 받은 뒤, Integer 클래스의 parseInt 메서드를 활용한다! int age = Integer.parseInt(scan.nextLine()); String grade = scan.nextLine(); System.out.println(age); System.out.println(grade); } }
'ProgrammingLanguage > Java' 카테고리의 다른 글
자바(Java) 싱글턴 패턴(Singleton Pattern) (1) 2021.01.23 자바(Java) BufferedReader 클래스 (0) 2021.01.18 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy) (0) 2021.01.13