Public

Pythonでの「EOF when reading a line」エラーの7つの解決方法

※本記事には広告・アフィリエイトリンクが含まれます

Python Python エラー対応
t-salad t-salad committed 6f7a2dc

Pythonスクリプトを実行したときに、次のようなエラーで止まることがあります。

スポンサーリンク
EOFError: EOF when reading a line

このエラーはinput()が標準入力(stdin)の終端に達したのに、まだ入力を読もうとしたときに発生します。ファイルの破損やPCの不具合ではありません。input()を使うコードが、入力が用意されていない状況で動いているのが原因のほとんどです。この記事では、実際に起きるパターン別に原因と正しい対処法を解説します。

前提: このエラーは input() が出すもの

まず切り分けとして重要な点です。ファイルオブジェクトのreadline()は、終端に達しても空文字列""を返すだけでこのエラーは出しませんEOFError: EOF when reading a lineが出るのは、input()(内部的に標準入力から1行読む関数)がもう読む行が無い状態で呼ばれたときだけです。したがって、原因は「ファイル」ではなく「標準入力の使い方」にあります。

原因1: 標準入力を読みすぎている(競技プログラミングで最頻)

AtCoderなどの競技プログラミングやオンラインジャッジで最も多いパターンです。与えられた入力の行数より多くinput()を呼ぶと、途中で入力が尽きてこのエラーになります。

# 入力が1行しか渡されていないのに input() を2回呼ぶ
a = input()
b = input()  # ここで EOFError: EOF when reading a line

input()の回数と、実際に渡される入力の行数が一致しているかを確認します。入力の形式(1行にまとめて渡されるのか、複数行なのか)を問題文で必ず確認してください。

原因2: パイプやリダイレクトで入力が尽きた

シェルからパイプやリダイレクトで入力を渡す場合も、渡した行数を超えてinput()を呼ぶと同じエラーになります。

echo "1" | python app.py    # 入力は1行だけ
python app.py < input.txt          # ファイルの行数までしか読めない

ループの中でinput()を無限に呼んでいると、入力の末尾で必ずEOFに達します。この場合は次の「正しい対処」のように終了を検知する書き方にします。

原因3: 対話入力を想定したスクリプトを非対話環境で実行している

次のような、標準入力が用意されない環境でinput()を実行すると即座にEOFになります。

  • IDEやエディタの実行機能で、標準入力欄が空のまま実行した
  • cron・CI・サブプロセスなど、対話端末を持たない環境で実行した
  • Jupyterやオンライン実行環境で、入力を渡さずにinput()を呼んだ

この場合は、そもそも入力を渡す(IDEの標準入力欄に値を入れる、パイプで渡す)か、入力が無い場合に備えて次の書き方でEOFを扱います。

スポンサーリンク

正しい対処: EOFErrorを終了条件として扱う

入力が「何行来るか分からない」ときは、EOFを正常な終了の合図として扱うのが定石です。input()を使うならtry/except EOFErrorでループを抜けます。

while True:
    try:
        line = input()
    except EOFError:
        break  # 入力の終端に達したらループを抜ける
    print(line)

より簡潔には、sys.stdinを直接イテレートする方法があります。こちらは終端で自然にループが終わるためEOFError自体が発生しません。

import sys

for line in sys.stdin:
    line = line.rstrip("\n")
    print(line)

標準入力を一度に全部読みたい場合は次のようにします。

import sys

data = sys.stdin.read().split("\n")

補足: ファイルの終端を判定したい場合

「ファイルを読んでいて終端を知りたい」という意図でこのエラーを検索した場合は、そもそも例外は発生しません。readline()は終端で空文字列を返すので、それで判定します。

with open("example.txt", "r", encoding="utf-8") as f:
    while True:
        line = f.readline()
        if line == "":   # 空文字列なら終端
            break
        print(line.rstrip("\n"))

通常は次のように、ファイルオブジェクトを直接イテレートするのが簡潔で安全です。

with open("example.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.rstrip("\n"))

まとめ

  • EOFError: EOF when reading a lineinput()が入力の終端で呼ばれたときのエラー
  • ファイル破損やPCの不具合が原因ではない(readline()は終端でも例外を出さない)
  • 競技プログラミングではinput()の回数と入力行数が合っているか確認する
  • 行数不定の入力はtry/except EOFErrorfor line in sys.stdinで終端を扱う
  • IDE・CI・cronなど非対話環境では、入力を渡すかEOFを想定した書き方にする

参考

関連書籍

スポンサーリンク
スポンサーリンク
★ この記事をXでシェア はてなブックマーク
関連記事