ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스트림(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은 공백 또는 개행 문자를 기준으로 입력 값들을 읽기 때문에, 사용자의 편의에 따라 쉽게 입력을 받을 수 있는 장점이 존재한다.

    출처 : https://docs.oracle.com/javase/7/docs/api/

     

    ※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);
    	}
    }

     

    댓글

Designed by Tistory.