Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 코린이
- node.js
- 초보개발자
- 상속
- FileInputStream
- 메서드
- 자바
- try-catch
- SSR
- ArrayList
- 인터페이스
- 보조 스트림
- 자료형
- 바이트 단위 스트림
- 졸리다
- 변수
- 개발자
- MPA
- 백엔드
- throws
- 파이팅
- Java
- 배열
- 다형성
- 코딩
- 새벽공부
- exception
- 문자 단위 스트림
- 인스턴스
- 예외 처리
Archives
- Today
- Total
SHUSTORY
[ 백준 ] 10951번 : A + B - 4 _ JAVA 본문
728x90
문제
- 띠용? 이 문제를 보고 굉장히 당혹스러웠다. 조건이 따로 없어?
입력이 끝날 때까지 A+B를 출력하는 문제. EOF에 대해 알아 보세요.
- 라는데.. EOF가 먼데요? 그래서 오늘은 EOF에 대해 알아보겠습니다!
내 풀이
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));
while(true) {
String st = br.readLine();
String[] tokens = st.split(" ");
int sum = Integer.parseInt(tokens[0]) + Integer.parseInt(tokens[1]);
bw.write(sum+"\n");
}
}
}
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));
while(true) {
String st = br.readLine();
String[] tokens = st.split(" ");
int sum = Integer.parseInt(tokens[0]) + Integer.parseInt(tokens[1]);
bw.write(sum+"\n");
}
}
}
- 런타임 에러
EOF
- End Of File
- 위 문제에서, 파일 종료 조건이 주어지지 않았다.
즉 입력에서 더 이상 읽을 수 있는 데이터가 존재하지 않을 때 (null) 반복문을 종료한다. - 문제에 입력이 끝나는 지점에 조건이 없다.
파일의 끝에서 입력받을 데이터가 없으면 알아서 종료 시키는 것을 EOF 처리라고 한다.
문제풀이 방법
- 처리하는 방법
- BufferedReader
- StringTokenizer 클래스 사용
- split( ) 보다 성능면에서 더욱 우월
- split( ) 메서드 사용
- StringTokenizer 클래스 사용
- Scanner
- Scanner의 메서드들은 더이상 읽을 데이터가 없으면 NoSuchElementException 을 예외가 발생한다.
해당 메서드는 두 가지 처리 방법이 있다.- try-catch문으로 예외 발생시 반복문을 종료해주도록 처리한다.
- Scanner의 메서드인 hasNext( )를 통해 처리한다.
- Scanner의 메서드들은 더이상 읽을 데이터가 없으면 NoSuchElementException 을 예외가 발생한다.
- BufferedReader
[ BufferedReader ]
- StringTokenizer 클래스 이용해 분리 / split( ) 메서드 이용
- readLine( ) 메서드를 이용하여 읽어온 값이 null인지 여부를 판단하여 while문 작성
- BufferedReader로 빈 값을 읽어들어오면 null로 받기 때문에 어떻게 보면 가장 단순하다고 볼 수 있음
- charAt( ) 메서드 사용 ( + StringBuilder )
- charAt( ) 메서드는 String으로 저장된 문자열 중 한 문자만 선택해 해당 문자의 아스키코드 값을 반환하기 때문에 숫자로 받기 위해 -48 또는 -'0'을 해주어야 한다.
- readLine( ) 메서드를 이용하여 읽어온 값이 null인지 여부를 판단하여 while문 작성
- BufferedReader - readLine( ) 사용 코드
import java.io.*;
import java.util.StringTokenizer;
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));
while(br.readLine()!=null){
StringTokenizer st = new StringTokenizer(br.readLine()," ");
int sum = Integer.parseInt(st.nextToken()) + Integer.parseInt(st.nextToken());
bw.write(sum+ "\n");
}
bw.flush();
bw.close();
br.close();
}
}
import java.util.StringTokenizer;
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));
while(br.readLine()!=null){
StringTokenizer st = new StringTokenizer(br.readLine()," ");
int sum = Integer.parseInt(st.nextToken()) + Integer.parseInt(st.nextToken());
bw.write(sum+ "\n");
}
bw.flush();
bw.close();
br.close();
}
}
- 그런데 위와 같이 코드를 작성하면 런타임 에러가 발생하고, 아래와 같이 코드를 작성하면 그렇지 않다.
그 이유는 무엇일까?
- 두 번의 readLine( ) 호출은 다음 입력 라인으로 이동하게 만든다.
첫 번째 호출에서 라인을 읽고, 두 번째 호출에서 다음 라인을 읽는다.
이로 인해 입력의 홀수 번째 라인이 누락되고, 입력과 출력 간의 불일치가 발생할 수 있다. - 아래의 코드는 readLine( ) 을 한 번 호출하고 그 결과를 변수 str에 저장한다.
이렇게 하면 한 번의 루프 반복에서 동일한 입력 라인을 사용하므로 불일치 문제가 발생하지 않는다.
- 두 번의 readLine( ) 호출은 다음 입력 라인으로 이동하게 만든다.
import java.io.*;
import java.util.StringTokenizer;
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));
String str;
while((str = br.readLine()) != null){
StringTokenizer st = new StringTokenizer(str," ");
int sum = Integer.parseInt(st.nextToken()) + Integer.parseInt(st.nextToken());
bw.write(sum+ "\n");
}
bw.flush();
bw.close();
br.close();
}
}
import java.util.StringTokenizer;
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));
String str;
while((str = br.readLine()) != null){
StringTokenizer st = new StringTokenizer(str," ");
int sum = Integer.parseInt(st.nextToken()) + Integer.parseInt(st.nextToken());
bw.write(sum+ "\n");
}
bw.flush();
bw.close();
br.close();
}
}
- charAt( ) / StringBuilder 사용 코드
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));
StringBuilder sb = new StringBuilder();
String str;
while ((str = br.readLine()) != null) {
int a = str.charAt(0) - 48;
int b = str.charAt(2) - 48;
sb.append(a + b).append("\n");
}
System.out.println(sb);
}
}
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));
StringBuilder sb = new StringBuilder();
String str;
while ((str = br.readLine()) != null) {
int a = str.charAt(0) - 48;
int b = str.charAt(2) - 48;
sb.append(a + b).append("\n");
}
System.out.println(sb);
}
}
[ Scanner ]
- hasNext( )를 사용한 EOF 처리 ( hasNextInt( )를 사용해도 된다 )
- while문의 조건에 EOF 처리를 위해 Scanner의 메서드 hasNext( )로 처리한다.
- hasNext( ) 메서드는 Boolean 값을 통해 다음 줄이 없으면 false를 반환하고 EOF의 끝을 알려 준다.
- hasNext( ) 메서드는 예외를 던지지 않고, 입력이 없으면 false를 반환한다.
따라서 hasNext( ) 로만은 입력이 없다는 것을 감지하고 예외를 발생시키기 어렵기에,
Scanner에서의 입력의 끝을 나타내는 EOF를 감지할 수 있는 방법은 다음과 같다.
다음을 통해 EOF가 입력되면 hasNext( )는 false를 반환하고, 반복문을 종료시킬 수 있다.
- Windows : Ctrl + Z
- Unix / Linux : Ctrl + D
- 정리하자면, Scanner 의 메서드들은 더 이상 읽을 데이터가 없으면 NoSuchElementException 예외가 발생한다.
하지만 space나 공백의 경우 예외를 반환하지 않기 때문에
while문에서 hasNext( ) 메서드를 사용하여 EOF일 경우 false 반환, 값이 있는 경우 true 반환해 처리한다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int a = sc.nextInt();
int b = sc.nextInt();
System.out.println(a + b);
}
sc.close();
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int a = sc.nextInt();
int b = sc.nextInt();
System.out.println(a + b);
}
sc.close();
}
}
- 순간 어라? while문의 조건이 sc.hasNext( ) 인데 어떻게 코드가 돌아가는거지? 처음에 값이 없는데 while문 조건식 자체가 성립이 안되어서 코드가 안돌아가는거 아니야? 라고 생각했는데 내가 잘못 받아들인거였다..ㅋㅋ 지금 머리가 안돌아가나? ㅜㅜ
- 입력값이 들어올 때까지 while문 내부가 실행되지 않다가, 입력값이 들어오면 조건문이 true를 return한 후에 while 문이 실행되는 것이다.
- 오늘은 여러가지 정리한 것이 많다! 복습 필수!!
'코딩테스트 > JAVA' 카테고리의 다른 글
[ 백준 ] 10818번 : 최소, 최대 _ JAVA (0) | 2023.12.02 |
---|---|
[ 백준 ] 10871번 : X보다 작은 수 _ JAVA (1) | 2023.12.02 |
[ 백준 ] 10952번 : A + B - 5 _ JAVA (0) | 2023.11.29 |
[ 백준 ] 2439번 : 별 찍기 - 2 _ JAVA (0) | 2023.11.29 |
[ 백준 ] 11021(2)번 : A + B - 7(8) _ JAVA (1) | 2023.11.28 |