Turbo C++ : while(fin) vs while(!fin.eof()) (Programare, Bucla While, Turbo C++, Dosbox, Fișiere De Date)

Alpha Mineron a intrebat.

Mi s-a spus că ar trebui să folosesc while(fin) în loc de while(!fin.eof()) la citirea unui fișier.

Care este diferența mai exact?

Editați: Știu că while(fin) verifică, de fapt, obiectul stream și că atunci când acesta devine NULL, bucla se întrerupe și acoperă stegulețele eof și fail.Dar profesorul meu de la curs spune că fin.eof() este mai bine, așa că trebuie să înțeleg operațiunea fundamentală care se întâmplă aici.

Care este practica corectă?

Notă: Nu este un duplicat, am nevoie de asistență în Turbo C++ și cu fișiere binare. practic încerc să citesc un fișier folosind un obiect de clasă.

Comentarii

  • Nu este răspunsul, dar omule, Turbo C++ este vechi… –  > Por HolyBlackCat.
  • Comparați cele două opțiuni atunci când apare o eroare în timpul citirii fișierului. –  > Por CodesInChaos.
  • @CodesInChaos Caut o explicație teoretică. Pot desigur să verific fin și fin.eof(). Și se pare că fin verifică, de asemenea, flag-ul fail împreună cu flag-ul eof, dar nu înțeleg cum funcționează. –  > Por Alpha Mineron.
  • @AlphaMineron În comentariul tău ai descris deja care este diferența, deci ce întrebi? Rezultă direct că while(fin.eof()) va intra într-o buclă nesfârșită dacă se întâlnește o eroare, în timp ce while(fin) iese din buclă. –  > Por CodesInChaos.
  • Obiectul stream nu devine de fapt nul. Acesta intră într-o stare invalidă, iar după aceea, obiectul său operator void*() returnează null deoarece se află într-o stare invalidă. (În C++ modern, este explicit operator bool() în schimb, dar Turbo C++ nu este cu siguranță modern). –  > Por aschepler.
3 răspunsuri
Băiatul care a trăit

În primul rând presupun că fin este al tău fstream obiect. Caz în care profesorul tău nu ți-ar fi spus să folosești while(fin.eof()) pentru citirea din fișier. Ea ar fi spus să folosiți while(!fin.eof()).

Permiteți-mi să vă explic. eof() este un membru al grupului fstream care returnează un true sau false în funcție de faptul dacă a fost atinsă sau nu valoarea End Of File (eof) a fișierului pe care îl citiți. Astfel, în timp ce eof() funcția returnează 0 înseamnă că sfârșitul fișierului nu a fost atins și bucla continuă să se execute, dar când eof() returnează 1 sfârșitul fișierului a fost atins și bucla iese.

while(fin) Bucla este introdusă deoarece fin returnează de fapt valoarea unei variabile indicator de eroare din interiorul obiectului clasă fin a cărei valoare este setată la 0 atunci când orice funcție, cum ar fi citirea, scrierea sau deschiderea, eșuează. Astfel, bucla funcționează atâta timp cât funcția de citire din interiorul buclei funcționează.

Personal, nu aș sugera niciuna dintre ele. Aș sugera

//să presupunem o clasă abc.

abc ob;


While(fin.read((char*)&ob, sizeof(ob)))
{}

Sau

While(fin.getline(parameters))
{}

Această buclă citește înregistrarea din fișier în interiorul condiției de buclă și, dacă nu s-a citit nimic din cauza faptului că s-a ajuns la sfârșitul fișierului, se iese din buclă.

Problema cu while(!fin.eof()) este că returnează 1 dacă s-a ajuns la sfârșitul fișierului. Sfârșitul fișierului este, de fapt, un caracter care este pus la sfârșitul fișierului. Astfel, atunci când funcția de citire din interiorul buclei citește acest caracter și setează o variabilă eof la 1. Tot ceea ce face de fapt funcția este să returneze această valoare.

Astfel, funcționează bine atunci când citiți linii în cuvinte, dar când citiți înregistrări succesive ale unei clase dintr-un fișier, această metodă va eșua.Considerați că

clas abc
{}a;

Fstream fin("file");


While(!fin.eof())


{
  fin.read((char*)&a,sizeof(a));


  a.display();  // display is a member function which displays the info }

Astfel afișează ultima înregistrare de două ori. Acest lucru se datorează faptului că caracterul de sfârșit de fișier este caracterul de după ultimul octet al ultimei înregistrări. Atunci când se citește ultima, pointerul de fișier se află la octetul eof, dar nu l-a citit încă. Astfel, se va intra din nou în buclă, dar de data aceasta este citit caracterul eof, dar funcția de citire eșuează. Valorile deja existente în variabila a, adică înregistrările anterioare vor fi afișate din nou.

Alpha Mineron

O metodă bună este de a face ceva de genul acesta:

while ( instream.read(...) && !instream.eof() ) {  //Reading a binary file
      Statement1;
      Statement2;
}

sau în cazul unui fișier text:

while ( (ch = instream.get()) && !instream.eof() ) {  //To read a single character
      Statement1;
      Statement2;
}

Aici, obiectul este citit în cadrul declarației de condiție a buclei while și apoi valoarea din ede este testată.Acest lucru nu ar avea ca rezultat ieșiri nedorite.

Aici se verifică starea operațiunii de intrare/ieșire propriu-zise și eof împreună. Puteți verifica, de asemenea, dacă există un indicator de eșec.

Aș dori să subliniez că, potrivit lui @RetiredNinja, putem verifica doar operațiunea de I/O. Adică:

while ( instream.read(...) ) {  //Reading a binary file
      Statement1;
      Statement2;
}

Haalef

O soluție rapidă și ușoară care a funcționat pentru mine pentru a evita orice problemă atunci când se utilizează eof este de a verifica după prima citire și nu ca o condiție a buclei while în sine. Ceva de genul acesta:

 while (true) // no conditions
 {
    filein >> string; // an example reading, could be any kind of file reading instruction

    if (filein.eof()) break; // break the while loop if eof was reached

    // the rest of the code
 }