BOJ

[백준 10871번/JAVA] X보다 작은 수 | BufferedWriter의 write()로 int형 출력하기

syj0522 2024. 3. 2. 12:40

문제

숫자를 입력받고, 주어진 수 X보다 작은 값을 출력하는 문제.

원래는 간단히 배열을 사용하는 문제인데 개인적으로 Buffer와 StringTokenizer을 사용하는 연습을 해보고싶어서 표준 출력이 아닌 Buffer를 사용해서 구현해보았다.

에러 : java.util.NoSuchElementException 

import java.util.*;  
import java.io.*;  
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));  
    StringTokenizer st;


        //N개의 정수들을 받아서 X와 비교하여 X보다 더 작으면 Buffer에 저장 후 출력
        st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int X = Integer.parseInt(st.nextToken());

        st = new StringTokenizer(br.readLine());
        for(int i=0; i<N; i++) {
            int num = Integer.parseInt(st.nextToken());
            if(num<X) {
                bw.write(num);
            }
        }
        bw.close();
    }
}

코드를 이렇게 짰는데, int num = Integer.parseInt(st.nextToken()); 에서 java.util.NoSuchElementException에러가 발생했다.

해결 : BufferedWrite에 값 저장 시 String으로변환

  • 코드 실행시킨 후 st에 정수 10개를 입력하고 표준출력으로 num을 콘솔창에 출력하니 for문이 한 번 돌 때마다 정수 10개가 하나씩 출력되었다. >> 토큰을 나누는 과정에서 에러는 없음
    • st객체에서 nextToken()메서드로 토큰을 하나씩 꺼내오면 st객체에는 토큰이 하나씩 없어진다. 이때 st객체 안에 가져올 토큰이 더 이상 없다면 NoSuchElementException 예외를 발생시킨다.
  • br.write(num);System.out.print(num);으로 변경하니 코드가 정상작동하였다. >> Buffer에 토큰을 저장하는 데 문제가 생긴 것으로 추측 
    • BufferedWrite에는 String값만 저장 가능하므로 String.valueOf() 또는 Integer.toString()으로 형변환 필요
  • bw.write(num);bw.write(Integer.toString(num)); 수정하니 정상작동하였다.

Java의 문자열 결합(concatenation) 기능

이 문제를 풀기 전에 백준 15552번을 풀었는데, A+B를 출력하되 입출력 속도 향상을 위해 BufferedReader을 사용하도록한 문제였다.


이때는 아래와 같이 write()메서드에 바로 int형 데이터를 저장하여 bw.close()로 출력했고 콘솔창에도 정수가 잘 출력되었다.

bw.write((Integer.parseInt(st.nextToken())) 
        + (Integer.parseInt(st.nextToken()))
        + "\n");

그래서 이번 문제를 풀 때도 마찬가지로 write()메서드에 int형 데이터를 저장하려고 했는데, 다른 점이 뭘까?

 

결론적으로는 위 코드는 write()메서드에 int형 데이터를 저장한 게 아니다. String을 저장한 것이다. 

 

java에서 문자열 외의 다른 데이터 타입을 + 연산자로 이어붙이면 해당 데이터는 문자열로 자동 변환되어 결합된다.

 

따라서 위의 코드는 두 정수형 데이터의 합이 먼저 계산되고, 그 결과가 문자열로 변환되어 BufferedWriter에 저장된 것이다.

 

이처럼 문자열 결합(concatenation)기능을 사용하면 굳이 정수형을 문자열로 변환하지 않고도 write()메서드를 통해 출력할 수 있다. 

 

마찬가지로 10871번의 코드도 bw.write(num + '\n');으로 작성하면 String으로 형변환한 것과 동일한 결과를 얻을 수 있다.