【C++】cin / ifstream で入力の終わり(EOF)を判定する方法

目次

はじめに

C++で、ファイルや標準入力から、データがいくつあるか分からないまま、全てのデータを読み終わりまで処理したい、という場面は非常に多くあります。このような場合、入力ストリームの状態をチェックして、ループを終了させる必要があります。

入力ストリームオブジェクト(cinifstreamなど)は、bool値が必要とされる文脈(while文やif文の条件式など)に置かれると、ストリームが正常な状態かを評価する特別な変換が行われます。

この記事では、この性質を利用して、入力の終わり(End-of-File, EOF)やエラーを検知し、ループを安全に終了させるための、C++における標準的なイディオム(定石)を解説します。


入力の終わりを判定するサンプルコード

このコードは、標準入力 (cin) からスペース区切りで入力された単語を、入力が終了するまで(Windowsなら Ctrl+Z, Linux/macOSなら Ctrl+D が押されるまで)一つずつ読み込み、出力します。

完成コード

#include <iostream>
#include <string>

using namespace std;

int main() {
    string word;
    
    cout << "単語をスペース区切りで入力してください (終了するにはEOFを入力):" << endl;
    
    // 1. whileの条件式の中で、入力と状態チェックを同時に行う
    while (cin >> word) {
        // 2. 読み込みが成功した場合のみ、このブロックが実行される
        cout << "読み取った単語: " << word << endl;
    }
    
    // 3. 入力が終了するとループを抜け、この行が実行される
    cout << "\n入力が終了しました。" << endl;
    
    return 0;
}

コードの解説

while (cin >> word)

これが、C++で入力の終わりを判定するための、最も重要で一般的なイディオムです。

  • cin >> word: この式は、まず cin から word 変数への読み込みを試みます。
  • 戻り値: そして、この抽出演算子 >> は、cin 自身への参照を返します。
  • 状態の評価: while 文の条件式に cin オブジェクトが置かれると、cin の状態が評価されます。
    • 読み込みが成功した場合: ストリームは「正常な」状態を保ち、true と評価されます。そのため、ループの本体が実行されます。
    • 読み込みが失敗した場合:
      • 入力の終端 (EOF) に達した。
      • int 型の変数に "abc" のような不正なデータが入力された。 といった理由で読み込みが失敗すると、ストリームは「エラー」状態になり、false と評価されます。そのため、ループは終了します。

ご提示のコード while(cin) も機能しますが、ループの中で cin >> s; と読み込むため、最後のループで読み込みが失敗した後に、ループ内の処理が一度余計に実行されてしまう可能性があります。while(cin >> variable) の形にすることで、この問題を回避できます。


まとめ

今回は、C++のストリームオブジェクトの性質を利用して、入力の終わりを判定する標準的な方法を解説しました。

  • while (ストリーム >> 変数) という構文を使うのが定石。
  • この構文は、読み込みが成功する間だけループを継続し、入力の終端 (EOF) やエラーで自動的にループを抜ける。
  • この方法は、cin(標準入力)だけでなく、ifstream(ファイル入力)や istringstream(文字列入力)でも全く同じように機能する。

このイディオムをマスターすれば、データソース(コンソール、ファイルなど)を意識することなく、統一的で堅牢な入力処理ループを記述することができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次