std::istream::eof în C++

Verifică starea unui flux: eof (sfârșitul datelor) și fail (citire eșuată).

Sintaxă
bool eof() const;   // s-a ajuns la sfârșitul datelor
bool fail() const;  // ultima operație a eșuat
void clear();       // resetează starea

Ce face std::istream::eof

Fiecare flux are câțiva indicatori de stare. eof() devine adevărat când o citire a încercat să treacă de sfârșitul datelor. fail() devine adevărat când o operație a eșuat: s-a terminat intrarea, textul nu era număr sau fișierul nu s-a deschis.

Diferența contează: când citirea se oprește, eof() adevărat înseamnă „s-au terminat datele”, iar fail() adevărat cu eof() fals înseamnă „am dat peste ceva greșit”. După o eroare, fluxul nu mai citește nimic până la clear().

eof() nu „prevede” sfârșitul: este adevărat abia după o citire care a dat de el. De aceea bucla corectă este while (flux >> x), nu while (!flux.eof()).

Ce returnează

true sau false.

Exemple

Exemplul 1: De ce s-a oprit citirea?

#include <iostream>
#include <sstream>

int main() {
    for (const char* date : {"10 20 30", "10 20 x 30"}) {
        std::istringstream in(date);
        int x, suma = 0;
        while (in >> x) {
            suma += x;
        }
        std::cout << "\"" << date << "\": suma " << suma << ", eof " << in.eof()
                  << ", fail " << in.fail() << '\n';
    }
}

Rezultat

"10 20 30": suma 60, eof 1, fail 1
"10 20 x 30": suma 30, eof 0, fail 1

Exemplul 2: Greșeala cu while (!eof())

Spațiul de la final face ca a patra citire să eșueze, dar bucla o numără totuși, pentru că verificarea se face înaintea citirii.

#include <iostream>
#include <sstream>

int main() {
    std::istringstream gresit("5 7 9 ");
    int x, cate = 0;
    while (!gresit.eof()) {
        gresit >> x;
        ++cate;
    }
    std::cout << "Cu !eof(): " << cate << " valori\n";

    std::istringstream corect("5 7 9 ");
    cate = 0;
    while (corect >> x) {
        ++cate;
    }
    std::cout << "Cu >> în condiție: " << cate << " valori\n";
}

Rezultat

Cu !eof(): 4 valori
Cu >> în condiție: 3 valori

Exemplul 3: Revenirea după o eroare cu clear()

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::istringstream in("12 kg 15");
    int a, b;
    std::string unitate;
    in >> a >> b;                       // b eșuează la „kg”
    std::cout << "fail după kg: " << in.fail() << '\n';
    in.clear();                         // ștergem eroarea
    in >> unitate >> b;
    std::cout << a << ' ' << unitate << ", apoi " << b << '\n';
}

Rezultat

fail după kg: 1
12 kg, apoi 15

Greșeli frecvente

  • Bucla while (!f.eof()) prelucrează o valoare în plus sau rămâne blocată la infinit dacă apare o eroare care nu este sfârșit de fișier (eof() nu devine niciodată adevărat).
  • Uiți clear() după o eroare: toate citirile următoare eșuează imediat, chiar dacă datele sunt corecte.

Comenzi înrudite

  • std::cin: Citește valori de la tastatură în variabile, cu operatorul >>.
  • std::ifstream: Deschide un fișier pentru citire și îl citește la fel ca pe std::cin.
  • std::istream::ignore: Sare peste caractere din intrare, de obicei până la sfârșitul rândului curent.
  • std::istream::seekg: Mută poziția de citire în flux (seekg) și arată poziția curentă (tellg).