[JAVA] Scanner / BufferReader 을 이용한 키 입력 (+next(),nextLine(),nextInt())

LeeSeungEun·2023년 5월 9일
0

JAVA

목록 보기
4/28

1. Scanner

  • 정규 표현을 사용해 원시적 형태 및 라인을 구문 분석할 수 있는 간단한 텍스트 스캐너이다.

    1) java.util 패키지 내에 위치한다.

    import java.util.Scanner;
    
    Scanner scanner = new Scanner(System.in);

    2) 버퍼의 사이즈가 1024byte (1KB)이다.
    3) 데이터를 파싱해서 원하는 type으로 가져온다.
    4) I/O Exception을 던지지 않는다.
    5) thread unsafe 한다.

    • 두 스레드에서 동일한 Scanner 인스턴스를 사용하는 경우 객체에 대한 액세스를 동기화하지 않으면 문제가 발생할 수 있다.

2. BufferedReader

  • 행을 효율적으로 읽을 수 있도록 문자를 버퍼링하여 문자 입력 스트림에서 텍스트를 읽는다.
    1) java.io 패키지 내에 위치하고 있다.

    • InputStreamReader 는 문자 기반의 보조 스트림으로써 바이트 기반 스트림을 문자 기반 스트림으로 연결시켜 주는 역할을 한다.

    • BufferedReader 와 System.in을 연결하기 위해 InputStreamReader를 사용한다.

        import java.io.BufferedReader;
        import java.io.InputStreamReader;
      
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

2) 버퍼의 사이즈가 8192byte (8KB)이다.

  • 버퍼를 이용해서 입출력의 효율을 높일 수 있도록 한다.

3) 데이터를 파싱하지 않은 채 가져온다.

  • String 으로만 읽고 저장한다.

4) I/O Exception을 던진다.

  • IOException을 throw 하거나 try/catch 해야한다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
    String a = br.readLine();
} catch (IOException e) {
    e.printStackTrace();
}
import java.io.*;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        // 스택 사용
        Stack<Integer> s = new Stack<>();

        int num = Integer.parseInt(br.readLine());

        for (int i = 0; i < num; i++) {
            String[] input = br.readLine().split(" ");

            switch (input[0]) {
                case "push":
                    s.push(Integer.parseInt(input[1]));
                    break;
                case "pop":
                    if (s.empty()) {
                        bw.write("-1" + "\n");
                    } else {
                        bw.write(s.pop() + "\n");
                    }
                    break;
                case "size":
                    bw.write(s.size() + "\n");
                    break;
                case "empty":
                    if (s.empty()) {
                        bw.write("1" + "\n");
                    } else {
                        bw.write("0" + "\n");
                    }
                    break;
                case "top":
                    if (s.empty()) {
                        bw.write("-1" + "\n");
                    } else {
                        bw.write(s.peek() + "\n");
                    }
                    break;
            }

        }
        bw.flush();
        bw.close();
    }
}
  • (참고) bw.flush(), bw.close()
    • bw.flush()는 버퍼에 남아있는 데이터를 출력 스트림으로 모두 전달하는 역할을 한다. bw.close()는 출력 스트림을 닫고 관련된 시스템 자원을 해제하는 역할을 한다.
    • 이 두 메소드는 파일이나 네트워크 연결과 같은 리소스를 사용하는 경우에 중요하다. bw.close()를 호출하면 출력 스트림이 닫히고, 관련 리소스가 해제되어 메모리 누수나 시스템 리소스 낭비를 방지할 수 있다.
    • 일반적으로 BufferedWriter를 사용한 후에는 bw.flush()를 호출하여 버퍼에 남아있는 데이터를 모두 출력하고, 마지막에 bw.close()를 호출하여 출력 스트림을 닫는 것이 좋다. 이를 통해 안정적인 프로그램 동작과 자원 관리를 할 수 있다.
    • 하지만 bw.close()를 호출하지 않고 프로그램이 종료되는 경우에는 자동으로 출력 스트림이 닫히고 리소스가 해제되기 때문에 큰 문제는 발생하지 않을 수 있다. 그러나 명시적으로 bw.close()를 호출하여 자원 관리를 하는 것이 권장되는 프로그래밍 습관이다.
// BufferedWriter 사용 하지 않고 구현
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 스택 사용
        Stack<Integer> s = new Stack<>();

        int num = Integer.parseInt(br.readLine());

        for (int i = 0; i < num; i++) {
            String[] input = br.readLine().split(" ");

            switch (input[0]) {
                case "push":
                    s.push(Integer.parseInt(input[1]));
                    break;
                case "pop":
                    if (s.empty()) {
                        System.out.println("-1");
                    } else {
                        System.out.println(s.pop());
                    }
                    break;
                case "size":
                    System.out.println(s.size());
                    break;
                case "empty":
                    if (s.empty()) {
                        System.out.println("1");
                    } else {
                        System.out.println("0");
                    }
                    break;
                case "top":
                    if (s.empty()) {
                        System.out.println("-1");
                    } else {
                        System.out.println(s.peek());
                    }
                    break;
            }

        }
    }
}
  • StringTokenizer 사용
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int e = Integer.parseInt(st.nextToken());
        int s = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int E = 0;
        int S = 0;
        int M = 0;
        int year = 0;
        while (true) {
            year++;
            E++;
            S++;
            M++;
            if (E == 16) E=1;
            if (S==29) S=1;
            if (M==20) M=1;
            if (e == E && m == M && S == s) break;
        }
        System.out.print(year);
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] input = br.readLine().split(" ");
        int e = Integer.parseInt(input[0]);
        int s = Integer.parseInt(input[1]);
        int m = Integer.parseInt(input[2]);

        int E = 0;
        int S = 0;
        int M = 0;
        int year = 0;

        while (true) {
            year++;
            E++;
            S++;
            M++;

            if (E == 16) E = 1;
            if (S == 29) S = 1;
            if (M == 20) M = 1;

            if (e == E && m == M && s == S) break;
        }

        System.out.print(year);
    }
}

5) thread safe 한다.

3. 메소드

  • next(), nextInt() 메소드 사용 시 버퍼에 엔터키가 남아있을 수 있다 (이 때, scanner.nextLine(); 한 줄 추가하여 방지)
  • char c = scanner.next().charAt(0)
    charAt()
    : String타입인 문자열을 char타입의 문자로 변환해주는 명령어
    String str = new String("예시");
    char c = str.charAt(0); // ( )안의 0은 해당 문자열의 인덱스 위치를 가리킨다.
  • String c = scanner.next()
  • String c = nextLine()
  • Int c = nextInt()
import java.util.Scanner;
 
public class ScannerEx {
 
    public static void main(String[] args) {
        
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("나이를 입력해 주세요.");
        int age = scanner.nextInt(); //정수형만 받는 메소드
        
        System.out.printf("내 나이는 %d세 입니다.",age);        
 
    }//main
 
}//class

4. Scanner 와 BufferedReader 의 차이점

1) Scanner 와 BufferedReader의 버퍼 사이즈가 각각 1KB, 8KB로 차이가 많이 난다. 그렇기 때문에 많은 입력이 있다고 한다면 BufferedReader가 좋다.
2) BufferedReader는 String으로만 읽고 저장하지만 Scanner는 다른 타입으로 파싱할 수 있다.
3) Scanner 는 Thread-safe하지 않기때문에 동일한 인스턴스 변수를 가지고 멀티 쓰레드에 사용할 수 없다.

5. 출처

https://shs2810.tistory.com/19

0개의 댓글