어제 오늘 내일

[Java] 키보드로 사용자 입력받는 2가지 방법 (BufferedReader, Scanner) 본문

IT/Java

[Java] 키보드로 사용자 입력받는 2가지 방법 (BufferedReader, Scanner)

hi.anna 2021. 5. 24. 06:39

다음의 2가지 방법으로

키보드로 사용자의 입력을 받아서 처리할 수 있습니다.

  1. BufferedReader, InputStreamReader, System.in
  2. Scanner

 

1. BufferedReader, InputStreamReader, System.in

System.in

일반적으로 keyboard 입력을 지칭하는 Standard Input Stream 입니다.

 

InputStreamReader

  • InputstreamReader (InputStream in)
  • InputstreamReader (InputStream in, String charsetName)
  • InputstreamReader (InputStream in, Charset cs)
  • InputstreamReader (InputStream in, CharsetDecoder dec)

byte stream을 character stream으로 변경해주는 역할을 합니다.

InputStreamReader 클래스는 생성자의 파라미터로 InputStream 객체를 전달 받습니다.

(이 InputStream 객체의 종류에 따라서,

키보드 사용자 입력을 읽어들일 수도 있고, 파일의 내용을 읽어들일 수도 있습니다)

또한, 생성자의 파라미터로 charset 정보를 전달받아서,

읽어들이는 stream의 charset을 지정할 수 있습니다.

 

BufferedReader

  • BufferedReader (Reader in)
  • BufferedReader (Reader in, int sz)

효율적으로 문자를 읽어들이기 위해서 버퍼링을 해 줍니다.

기본 버퍼 사이즈를 그대로 이용해도 되고, 생성자를 이용하여 버퍼 사이즈를 지정해 줄 수도 있습니다.

보통, FileReader, InputStreamReader의 read()와 같이 비용이 많이드는 Reader를 파라미터로 전달받아서 사용합니다.

만약, BufferedReader 없이 FilerReader나 InputStreamReader를 사용하면

시스템은 바이트별로 사용자의 입력을 받아서 처리하는 동작을 반복합니다.

(시스템에서 IO는 자원소모가 많습니다)

BufferedReader를 사용하면,

시스템은 버퍼가 비어있을 때만, 실제 IO를 일으켜서 데이터를 읽어오고,

나머지 경우에는 메모리에 있는 버퍼의 데이터를 읽어서 처리합니다.

 

좀 복잡해 보이지만, 위 3개 클래스를 이용해서 사용자의 입력을 받는 예제입니다.

  예제 1 - 사용자 입력 1번 받기  

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class UserInput {
    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        // 입력 데이터 읽기
        String str = reader.readLine();  // Hi Anna

        // 입력 데이터 출력
        System.out.println(str);  // Hi Anna

    }
}

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

BufferedReader, InputStreamReader, System.in을 이용하여

키보드 사용자 입력을 받을 수 있는 객체를 생성하였습니다.

 

String str = reader.readLine();

BufferedReader의 readLine() 메소드를 이용하여 사용자 입력 한 줄을 받습니다.

 

  예제 2 - 반복해서 사용자 입력 받기  

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class UserInput {
    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        // 반복해서 입력 데이터 읽기
        String str;
        while ((str = reader.readLine()) != null) {
            System.out.println(str);
        }
    }
}

위 코드는 반복적으로, 계속해서 한줄씩 사용자 입력을 받고 출력합니다.

 

 

2. Scanner

Scanner 크래스를 이용하면,

앞에서 소개한 방법보다 조금 더 쉽게 사용자 키보드 입력을 받을 수 있습니다.

또한, 입력받은 데이터를 Scanner 클래스의 메소드를 이용하여, 좀 더 쉽게 가공할 수 있습니다.

 

  예제 1 - Scanner로 사용자 입력 받기  

import java.util.Scanner;

public class ScannerInput {
    public static void main(String[] args) {

        // scanner 선언
        Scanner scanner = new Scanner(System.in);

        // 사용자 입력
        System.out.println("문자열을 입력하세요 : ");
        String str = scanner.nextLine();

        System.out.println("정수를 입력하세요 : ");
        int number = scanner.nextInt();

        System.out.println("실수를 입력하세요 : ");
        float floatNumber = scanner.nextFloat();

        System.out.println("true/false를 입력하세요 : ");
        boolean bool = scanner.nextBoolean();

        // 결과 출력
        System.out.println(str);
        System.out.println(number);
        System.out.println(floatNumber);
        System.out.println(bool);

        // close scanner
        scanner.close();
    }
}

  결과  

// 입력
문자열을 입력하세요 : 
hi
정수를 입력하세요 : 
3
실수를 입력하세요 : 
3.3
true/false를 입력하세요 : 
false

// 출력
hi
3
3.3
false

Scanner scanner = new Scanner(System.in);

Scanner로 Standard Input Stream을 전달하여,

키보드에서 입력을 받을 수 있는 Scanner 객체를 하나 생성하였습니다.

 

scanner.nextLine();

입력 받은 데이터 한 줄을 읽어서, String으로 리턴합니다.

 

scanner.nextInt();

scanner.nextFloat();

scanner.nextBoolean();

Scanner의 nextXXX() 메소드를 이용하여

사용자로부터 입력받은 토큰(token)을 String, int, boolean 등의 타입으로 변환할 수 있습니다.

(여기에서 token은 공백 문자 ('\t', '\f', '\r', ' ', '\n')를 말합니다.)

예제에 있는 메소드 이외에도

nextBigDecimal(), nextBigInteger(), nextByte(), nextDouble(), nextLong(), nextShort() 메소드를 사용하여 입력받은 데이터를 원하는 타입으로 변환할 수 있습니다.

 

scanner.close();

다 사용한 scanner를 close 해 줍니다.

 

  예제 2 - Scanner로 사용자 입력 반복해서 받기  

import java.util.Scanner;

public class ScannerLoop {
    public static void main(String[] args) {
        
        // Scanner 선언
        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNextLine()) {
            String str = scanner.nextLine();
            System.out.println(str);
        }

        scanner.close();
    }
}

  결과  

11  // 입력
11  // 출력
hello  // 입력
hello  // 출력
hi anna  // 입력
hi anna  // 출력
...

scanner.hasNextLine();

이 메소드는 Scanner가 더 읽어들일 Line이 있는지를 체크하여 true/false를 리턴합니다.

이 메소드는 더 읽어들일 Line이 있는지 검사만 할 뿐, 실제로 값을 읽어들이지는 않습니다.

따라서, hasNextLine()으로 더 읽어들일 Line이 있는지 while의 조건문에서 검사한 후,

읽어들일 값이 있으면 (hasNextLine()의 결과가 true이면)

while 문의 body에서 nextLine() 메소드를 이용하여 

실제 값을 읽도록 처리합니다.

 

  예제 3 - Scanner로 token 단위로 사용자 입력 처리하기  

import java.util.Scanner;

public class ScannerLoop {
    public static void main(String[] args) {
        
        // Scanner 선언
        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNext()) {
            String str = scanner.next();
            System.out.println(str);
        }

        scanner.close();
    }
}

  결과  

// 사용자 입력
hi hello Anna 

// 출력
hi
hello
Anna

예제 2가 라인별로 사용자 입력을 읽어들였다면,

이번 예제는 token(공백)별로 사용자 입력값을 읽어들입니다.

위 예제에서는 한 줄에 "hi hello Anna"라고, 공백으로 구분된 문자열을 입력하였습니다.

 

scanner.hasNext();

hasNext() 메소드를 이용하여

다음으로 읽어들일 token이 있는지 체크합니다.

 

scanner.next();

token별로 입력값을 읽어들여서 String을 리턴합니다.

 

 


 

  • BufferedReader, InputStreamReader, System.in
  • Scanner

두 가지 방법으로 키보드 사용자 입력을 처리하는 방법을 알아보았습니다.

 

 

 

반응형
Comments