본문 바로가기
개발 공부/Java

[자바다] System.in.read() 사용법을 반복문 그리고 엔터와 함께 살펴보기

by 반달bear 2022. 9. 27.
반응형

백준 10871 문제를 풀다가 발견한 System.in.read() 코드! 10871번: X보다 작은 수 (acmicpc.net)

저는 BufferedReader을 사용해서 문제를 풀었는데 시간을 훨씬 단축시킨 사람들 코드를 보니 System.in.read()을 사용하고 있었습니다. 그런데 이해가 잘 가지 않아서 혹시 저와 같은 사람이 있을까봐 글을 씁니다.

 

 

우선 System.in.read()는 문자 char타입인 문자 하나를 입력값으로 받고 그 문자에 대응하는 아스키 코드를 int값으로 출력하는 코드입니다. 

이 문제는 공백을 포함한 긴 문자열인 '10 5 \n'를 입력값으로 받은 후 System.in.read()로 읽어들여야 하는데요 System.in.read()는 '문자 하나'만을 입력으로 받습니다. 그럼으로 System.in.read()를 간단하게만 보면 두가지 문제가 생깁니다. 

  1. 10을 어떻게 입력값으로 받을까 (10은 1이라는 문자와 0이라는 문자로 이루어진 2가지 문자입니다. 읭?? 싶으신 분들은 아스키코드를 검색검색 고~~~)
  2. 숫자 하나만 읽고 끝나는 것이 아니고 \n를 만날때까지 계속 입력값을 읽어들여야 함

 

 

이 문제를 해결하기 위해선 버퍼에 대한 이해가 있어야 합니다. 

간단하게 그려봤는데요...ㅎㅎ 

컴퓨터와 키보드 사이엔 입력스트림이란게 있습니다. 키보드에서 '10 5 \n'를 입력하면 입력스트림에 '10 5 \n'가 줄을 쭉 서서 System.in.read()라는 버스를 기다려요! 이 버스는 문자 1개가 최대 정원이라 처음 '1'을 태우면 '0 \n'는 기다려야 합니다. 

그리고 입력이 끝난다고 해서 버스줄이 사라지지 않고 다음 System.in.read() 버스가 오면 '0'이 버스를 타고 컴퓨터로 가요. 

 

class Main{

	int num = read();
        System.out.println("num"+num);

        //int baseNum = read();
        //System.out.println("baseNum"+baseNum);

    }
     public static int read() throws IOException {
        int totalValue=0;
        int input;
        while(true){ 
            input = System.in.read();
            
            System.out.println("input"+(input-48));
            //input -48은 아스키를 고려한 것입니다.
            if(input=='\n' || input==' ') {       
                System.out.println("return"+(totalValue));
                return totalValue;
            } else {
                totalValue = 
                (totalValue*10) 
                + (input-48);
            }
        }
     }

<결과값>

'10 5\n'를 입력했을 때의 결과값입니다. '10 5\n'가 입력 스트림에 들어갔고 System.in.read()버스가 첫 문자인 1을 데리고 컴퓨터로 들어갔어요. 그 다음 두번째 문자인 0을 데리고 컴퓨터로 들어가고 마지막 문자인 ' ' 를 데리고 컴퓨터로 들어왔습니다! 그리고 컴퓨터로 들어온 모든 문자열을 이렇게 저렇게 만져서 10이라는 숫자를 리턴하고 num에 숫자 10이 저장되었네요. 이건 제가 공백이나 엔터를 만나기 전까지 이 메소드에 머무르게 하기 위해 반복문에 가두어 놨기 때문입니다.

기억해야 할 부분은 반복문이 끝나고 리턴문으로 Main에 돌아갔다고 버스 대기줄이 사라지는 건 아니라는 것입니다.

 

<주석 처리된 부분을 해제하고 실행 했을 때의 결과값>

'10 5\n'에서 '10 '가 입력스트림에서 컴퓨터로 들어가고 종료되었더라도 '5\n'라는 버스 대기줄은 여전히 존재하고 다시 System.in.read() 라는 버스가 운행하면 나머지 숫자들이 컴퓨터로 이동하는 것을 확인할 수 있습니다. 

 

 

System.in.read() 코드를 이해하는데 도움이 되었으면 좋겠네요! 

 

 

 

반응형

댓글