본문 바로가기

Algorithm

[입출력] boj 11718, 11719 - EOF 판단

백준 11718, 11719는 간단한 문제지만 설명하자면 어렵다. 언어에 대한 이해가 부족해서 그런 것 같다.

출제 의도

사이트에서 주는 FAQ 내용을 가져오자면 아래와 같다.

이 문제의 목적은 문자열을 올바르게 입력받고 파일의 끝(EOF)을 올바르게 판단하는 법을 연습하는 것입니다. 총 몇 줄이 주어진다 등의 정보는 절대 입력으로 주지 않습니다. 또한 단순히 키보드로 입력 내용만 적고 프로그램이 종료되지 않은 상태까지만 봐서는 EOF를 제대로 처리했는지 알 수 없습니다. 더 이상 읽을 게 없을 때 프로그램을 종료하는 법을 알아야 합니다. 그 방법은 언어마다 다르고 사용하는 함수마다 다르니 검색해서 그 방법을 알아보세요. 주로 파일 입출력으로 설명되어 있겠지만, 입력 스트림도 파일 입력이기 때문에 결국 동일합니다. 언어를 불문하고, 레퍼런스를 참고해서 사용법을 정확하게 숙지하는 습관을 들이세요.

  1. (Python) input()은 EOFError를 발생시킵니다.

  2. (Python) sys.stdin.readline()은 빈 문자열을 반환합니다.

EOF 판단은 파이썬을 처음 접하면서 IDLE을 쓸 때만 생각해봤다. 그래서 이 문제를 풀 때 '그대로 출력하기'만 생각하다 당황했다.

 


성공한 코드

이게 정석인 것 같다. input이 파일의 끝에서 주는 EOFError로 EOF를 판단하고 프로그램을 종료하기.

 

while(True):
    try:
        print(input())
    except EOFError:
        break

 

read()는 전체를 하나의 문자열로 읽는다. input을 통째로 갖다 output으로 넣는 셈.

import sys

print(sys.stdin.read())

 

이건 sys.stdin.readline()이 EOFError대신 빈 문자열을 return하는 걸 이용하는 방법이다. rstrip()은 readline()이 가져오는 \n을 떼기 위한 거다. 근데 만일 출력해야되는 input에 문자열 우측 공백이 포함되어 있거나 빈 문자열이 있으면 이 방법으론 안 될 거 같다.

import sys

while True:
    line = sys.stdin.readline().rstrip()
    if line != "":
        print(line)
    else:
        break

틀린 코드

readline()이 매 줄마다 \n도 끌고 올거고, EOF에서 빈 문자열을 돌려줄 테니 틀린 코드다.

import sys

print(sys.stdin.readline())

 

출력 형식이 잘못되었다. readline()이 가져오는 \n 때문.

import sys

while True:
    line = sys.stdin.readline()
    if line != "":
        print(line)
    else:
        break

 

출력 초과. readline()이 EOF에서 return하는 건 에러가 아니라 빈 문자열이니 except로 빠지지 않는다. 그래서 프로그램이 EOF에서 종료되지 않고 빈 문자열만 나올테니 출력 초과인 거라고 생각한다.

import sys

while(True):
    try:
        print(sys.stdin.readline().strip())
    except:
        break