Biblioteca
Tutora
BibliotecaInformatică și TIC › clasa a VII-a

Fișiere

Elevii învață să lucreze cu fișiere text pentru stocarea și prelucrarea datelor persistente.

De ce avem nevoie de fișiere

Până acum, programele tale primeau datele de la tastatură și afișau rezultatele pe ecran. Problema: când programul se închide, totul dispare — variabilele trăiesc doar în memoria RAM, care se golește la oprirea programului. Ca datele să supraviețuiască, ele trebuie salvate pe disc, într-un fișier.

Un fișier este o colecție de date memorată pe un suport de stocare (SSD, hard disk, stick USB), identificată printr-un nume și o extensie (de exemplu note.txt). Spre deosebire de RAM, discul păstrează datele și după oprirea calculatorului — spunem că fișierele oferă persistența datelor.

În programare, la clasa a VII-a lucrăm cu fișiere text: fișiere care conțin caractere lizibile, organizate pe rânduri — exact ce ai vedea deschizându-le cu Notepad. Numerele sunt scrise ca șiruri de cifre despărțite prin spații sau rânduri noi. Prin contrast, fișierele binare (imagini, muzică, programe executabile) conțin octeți care nu sunt text și arată ca niște semne fără sens într-un editor — ele se studiază la liceu.

De ce preferă problemele fișierele în locul tastaturii?

Deschiderea și închiderea fișierelor în C++

Ca să lucrezi cu fișiere în C++, incluzi biblioteca <fstream> și folosești două tipuri de obiecte-flux, surori cu cin și cout:

Declararea și deschiderea se fac de obicei împreună:

ifstream fin(numele fișierului de intrare); ofstream fout(numele fișierului de ieșire);

Din acest moment, fin se folosește exact ca cin, iar fout exact ca cout — aceleași săgeți >> și <<. Aceasta e marea eleganță a limbajului: schimbi doar sursa datelor, restul programului rămâne identic.

Reguli și capcane la deschidere:

Citirea datelor din fișier

Citirea cu fin >> variabila funcționează ca la tastatură: sare peste spații și rânduri noi și extrage următoarea valoare. Pentru un fișier care conține pe primul rând numărul n și pe al doilea rând n numere, citirea este:

fin >> n; for (i = 0; i < n; i++) fin >> v[i];

Observă că programului nu îi pasă dacă numerele sunt pe același rând sau pe rânduri diferite — operatorul >> le găsește oriunde. Aceasta e o sursă de mirare la început: aranjarea pe rânduri contează pentru ochiul omului, nu pentru >>.

Situația specială, cerută des în probleme: fișierul conține numere fără să știm câte — citim până se termină fișierul. Idiomul consacrat:

while (fin >> x) { prelucrează x }

Expresia fin >> x este adevărată cât timp citirea reușește și devine falsă la sfârșitul fișierului (end of file — EOF). Bucla se oprește singură exact când datele s-au terminat — șablonul standard pentru „se citesc toate numerele din fișier”.

Două greșeli de evitat:

Scrierea datelor în fișier

Scrierea cu fout << valoare este oglinda perfectă a lui cout: aceleași reguli, aceleași obiceiuri:

Ce trebuie să îți intre în reflex la probleme:

Mai ține minte diferența de comportament: dacă rulezi programul de două ori, fișierul de ieșire este rescris de la zero de fiecare dată (conținutul vechi dispare la deschidere), nu se adaugă la coadă. Modul de scriere „cu adăugare” (append) există, dar nu este comportamentul implicit și nu se cere la acest nivel.

Aplicații tipice cu fișiere text

Problemele cu fișiere sunt aceleași probleme pe care le știi deja — sume, maxime, numărări, vectori — doar că datele vin din fișier și rezultatele pleacă în fișier. Tiparele consacrate:

Strategia de verificare înainte de predare: deschide fișierul de ieșire și compară-l vizual cu formatul cerut de enunț (numărul de rânduri, separatorii); apoi testează și cazurile-limită — fișier cu un singur număr, fișier în care toate valorile sunt egale. Programele care pică testele de concurs pică aproape întotdeauna pe format sau pe cazuri-limită, nu pe algoritmul principal.

De reținut

fișier
colecție de date memorată pe un suport de stocare, identificată prin nume și extensie, care păstrează datele și după oprirea programului
persistența datelor
proprietatea datelor salvate în fișiere de a supraviețui închiderii programului și opririi calculatorului, spre deosebire de variabilele din memoria RAM
fișier text
fișier care conține caractere lizibile organizate pe rânduri, cu numerele scrise ca șiruri de cifre despărțite prin spații sau rânduri noi
ifstream
flux de citire dintr-un fișier în C++ (biblioteca fstream); se folosește cu operatorul >>, exact ca cin
ofstream
flux de scriere într-un fișier în C++; se folosește cu operatorul <<, exact ca cout; creează fișierul dacă nu există și îi șterge conținutul dacă există
close()
operația de închidere a unui fișier; la fișierele de ieșire garantează că datele din zona tampon ajung efectiv pe disc
sfârșitul fișierului (EOF)
momentul în care nu mai există date de citit; expresia fin >> x devine falsă, oprind natural bucla while (fin >> x)
citire până la capăt
șablonul while (fin >> x) folosit când numărul valorilor din fișier nu este cunoscut dinainte
buffer (zonă tampon)
zonă intermediară de memorie prin care trec datele scrise; explică de ce un fișier neînchis poate rămâne gol sau incomplet

Greșeli frecvente

Greșit: Rularea programului cu fișierul de intrare inexistent sau aflat în alt folder decât programul
Corect: Fișierul de intrare trebuie să existe în folderul programului (sau să fie indicat cu calea completă); altfel citirea eșuează și variabilele rămân cu valori neinițializate
Greșit: Presupunerea că deschiderea unui fișier de ieșire existent păstrează conținutul vechi
Corect: ofstream șterge la deschidere tot conținutul anterior al fișierului; scrierea începe de la zero la fiecare rulare, iar datele vechi se pierd fără avertisment
Greșit: Citirea unui număr necunoscut de valori cu o buclă care nu verifică reușita citirii
Corect: Șablonul corect pune citirea chiar în condiție: while (fin >> x); după sfârșitul fișierului, o citire cu >> nu mai umple variabila și s-ar prelucra valori rămase de la pasul anterior
Greșit: Memorarea tuturor valorilor într-un vector chiar și pentru sumă, maxim sau numărare
Corect: Aceste prelucrări se fac direct la citire, cu un acumulator; vectorul e necesar doar când valorile trebuie revizitate ulterior
Greșit: Ignorarea formatului de ieșire cerut de enunț (separatori, rânduri)
Corect: Evaluarea automată compară fișierul de ieșire caracter cu caracter; separatorii și rândurile noi se scriu exact ca în enunț, altfel răspunsul e respins chiar cu valori corecte

Test — 6 întrebări ca la examen

1. Care este motivul principal pentru care un program salvează datele într-un fișier în loc să le țină doar în variabile?
  1. fișierele fac programul să ruleze mai repede
  2. variabilele din RAM dispar la închiderea programului, iar fișierele păstrează datele pe disc
  3. variabilele pot memora doar numere mici
  4. fișierele nu pot fi șterse niciodată
Vezi răspunsul
variabilele din RAM dispar la închiderea programului, iar fișierele păstrează datele pe disc. Fișierele oferă persistență: datele supraviețuiesc închiderii programului și opririi calculatorului, pentru că stau pe disc, nu în RAM. Distractorul cu viteza e chiar inversul realității — accesul la disc e mai lent decât accesul la memorie.
2. În C++, pentru a citi date dintr-un fișier text se folosește un obiect de tip:
  1. ofstream, cu operatorul <<
  2. ifstream, cu operatorul >>
  3. ifstream, cu operatorul <<
  4. cout, cu operatorul >>
Vezi răspunsul
ifstream, cu operatorul >>. ifstream (input file stream) citește, folosind >> exact ca cin. Varianta a treia încurcă operatorii: săgețile arată sensul datelor — spre variabilă la citire (>>), dinspre variabilă la scriere (<<); ofstream și cout sunt pentru scriere, respectiv afișare.
3. Fișierul de ieșire rezultate.txt există deja și conține date de la o rulare anterioară. Ce se întâmplă la o nouă deschidere cu ofstream?
  1. noile date se adaugă după cele vechi
  2. programul se oprește cu eroare, fișierul existând deja
  3. conținutul vechi se șterge și scrierea începe de la zero
  4. conținutul vechi rămâne, iar noile date îl suprascriu doar parțial
Vezi răspunsul
conținutul vechi se șterge și scrierea începe de la zero. Deschiderea implicită cu ofstream golește fișierul existent; fiecare rulare pornește cu fișier de ieșire curat. Adăugarea la coadă (prima variantă) există ca mod special (append), dar nu e comportamentul implicit — exact confuzia pe care o testează întrebarea.
4. Fișierul de intrare conține un număr necunoscut de valori întregi. Care secvență le prelucrează corect pe toate?
  1. while (fin >> x) s += x;
  2. fin >> n; for (i = 0; i < n; i++) { fin >> x; s += x; }
  3. for (i = 0; i < 100; i++) { fin >> x; s += x; }
  4. do { fin >> x; s += x; } while (x != 0);
Vezi răspunsul
while (fin >> x) s += x;. while (fin >> x) citește cât timp mai există date și se oprește singur la sfârșitul fișierului — șablonul standard când numărul valorilor nu e cunoscut. A doua variantă presupune că n e scris în fișier (nu e cazul aici), a treia ghicește o limită, iar a patra se oprește greșit la orice valoare 0 din date.
5. Un elev scrie rezultatele cu fout, dar uită fout.close() la final, iar fișierul rămâne uneori gol. Care este explicația?
  1. fără close(), fișierul se șterge automat
  2. datele scrise trec printr-o zonă tampon, iar închiderea garantează ajungerea lor pe disc
  3. close() este cel care creează fișierul
  4. operatorul << nu funcționează fără close()
Vezi răspunsul
datele scrise trec printr-o zonă tampon, iar închiderea garantează ajungerea lor pe disc. Scrierea trece printr-un buffer; close() „împinge” pe disc tot ce a rămas în el. Fără închidere, datele pot rămâne blocate în tampon și fișierul apare gol sau incomplet. Fișierul e creat la deschidere, nu de close() — distractorul al treilea inversează momentele.
6. Fișierul de intrare conține: 4 pe primul rând și 10 20 30 40 pe al doilea. Ce afișează: fin >> n; s = 0; for (i = 1; i <= n; i++) { fin >> x; s += x; } cout << s;?
  1. 104
  2. 100
  3. 96
  4. 4
Vezi răspunsul
100. Primul număr citit este n = 4, apoi se citesc și se adună exact 4 valori: 10 + 20 + 30 + 40 = 100. Distractorul 104 apare la cine crede că și n intră în sumă, iar 4 la cine oprește citirea după primul rând — operatorul >> nu ține cont de rânduri, ci doar de ordinea valorilor.
Deschide varianta interactivă — cu AI care îți explică
← Subprograme (proceduri și funcții)Sisteme de calcul și rețele de calculatoare →
BiologieChimieEconomieFilosofieFizicăGeografieInformatică și TICIstorieLogică și argumentareMatematicăPsihologieLimba și literatura română