De ce while(!eof()) citește greșit un fișier C++
Leagă prelucrarea de reușita citirii, nu de o predicție despre sfârșitul fișierului. Evită repetarea ultimei valori și buclele pe intrare invalidă.
În acest material
Indicatorul eof descrie o stare observată de operațiile de citire. Nu este un detector care promite că următoarea extragere va reuși. De aceea, o buclă care verifică doar !eof() înainte de citire poate prelucra date după ce extragerea a eșuat.
Reușita citirii trebuie să controleze prelucrarea
Pentru o succesiune de numere până la sfârșitul fișierului, forma conceptuală este „cât timp pot citi un număr, îl prelucrez”. În C++, condiția while (fin >> x) leagă intrarea în corpul buclei de starea fluxului după extragere.
Nu este necesar să ghicești câte caractere mai există. Dacă ultima citire nu produce un număr valid, corpul nu mai rulează. Astfel eviți prelucrarea unei valori care nu a fost obținută printr-o citire reușită în acea iterație.
Spațiul de la final schimbă momentul observării
Un fișier poate avea spații sau un sfârșit de linie după ultimul număr. Fluxul poate afla că nu mai există alt număr abia la următoarea încercare de extragere. O condiție verificată înaintea acelei încercări nu spune dacă ea va reuși.
Acesta este motivul pentru care testele cu și fără linie nouă la final pot avea comportamente aparent diferite într-un program greșit. Soluția nu este modificarea fișierului, ci verificarea rezultatului operației care produce datele.
Pentru un fișier cu 7 și 9 urmate de spații, cele două citiri reușite se prelucrează. Încercarea următoare eșuează și nu produce o a treia valoare.Mărește schema ↗
Intrarea invalidă este alt caz de oprire
Dacă apare text unde se așteaptă un număr, citirea poate eșua fără ca problema să fie sfârșitul fișierului. O buclă bazată numai pe eof poate continua fără progres. După buclă, dacă aplicația trebuie să distingă fișierul valid de cel corupt, inspectează cauza opririi.
Pentru date organizate în perechi, condiția trebuie să ceară ambele valori înainte de prelucrare. O ultimă pereche incompletă nu trebuie transformată într-o înregistrare completă folosind accidental o valoare anterioară.
Teste mici și decisive
Folosește un fișier gol, unul cu un singur număr și unul cu două numere urmate de spații. Adaugă o intrare invalidă la mijloc și o pereche incompletă dacă formatul cere perechi. Numără câte înregistrări valide sunt prelucrate, nu doar suma finală.
Continuă cu fișierele în C++, operațiile de intrare și structurile repetitive.
Întrebări frecvente
De ce while(!fin.eof()) poate procesa o valoare în plus?
Starea de sfârșit este observată în urma citirii, nu prezice succesul următoarei extrageri. Bucla poate intra în corp, citirea poate eșua, iar codul poate prelucra o valoare care nu a fost citită atunci.
Cum citesc corect numere până la sfârșitul fișierului?
Leagă repetarea de extragerea reușită: while (fin >> x). Corpul buclei se execută numai după ce valoarea a fost citită cu succes.
Cum citesc toate liniile unui fișier, inclusiv pe cele goale?
Folosește succesul lui getline drept condiție de repetare. O linie goală citită cu succes este tot o linie; nu o confunda cu eșecul citirii sau cu sfârșitul fișierului.