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).