Tematică științifică · 2.4
Fișiere text
Definirea fișierelor text, deschiderea, citirea, scrierea și închiderea lor, transferul datelor și verificarea sfârșitului de fișier, în C++ și în Python.
Spre deosebire de datele stocate în variabile, conținutul fișierului nu dispare când programul se încheie. Programul poate deschide fișierul, poate transfera date între fișier și memoria internă, apoi îl închide.
La examen, fișierele text apar de obicei ca sursă de date pentru problemă: programul citește numere, cuvinte sau linii dintr-un fișier și afișează rezultatul pe ecran ori îl scrie într-un alt fișier.
Ce trebuie făcut, în ordine
Orice prelucrare corectă a unui fișier are aceleași etape:
- declararea obiectului sau a variabilei care reprezintă fișierul;
- deschiderea fișierului în modul potrivit;
- verificarea faptului că deschiderea a reușit;
- citirea din fișier sau scrierea în fișier;
- prelucrarea datelor în memoria programului;
- închiderea fișierului.
Fișier de intrare și fișier de ieșire
Același fișier poate fi deschis pentru citire și scriere, dar la problemele de examen se folosesc, de regulă, două fișiere cu roluri clare.
| Operație | Direcția transferului | Exemplu |
|---|---|---|
| citire | fișier → memorie | se citește un număr în x |
| scriere | memorie → fișier | se scrie valoarea lui rezultat |
| afișare | memorie → ecran | se scrie rezultatul cu cout sau print |
Un nume de fișier este un șir de caractere. El trebuie scris exact cum este
precizat în enunț, inclusiv extensia, de exemplu date.in sau titu2026.txt.
Când citirea ajunge în această poziție, nu mai există date de extras, iar o nouă încercare de citire eșuează.
Operații cu fișiere în C++ și Python
Fișiere text în C++
În C++, programul lucrează cu un fișier text prin intermediul unui flux. Fluxul se declară, se deschide, se folosește pentru citire sau scriere și se închide.
Fluxurile pentru fișiere
Biblioteca <fstream> pune la dispoziție clasele folosite pentru fișiere:
| Clasă | Rol |
|---|---|
ifstream | flux de intrare, pentru citirea din fișier |
ofstream | flux de ieșire, pentru scrierea în fișier |
fstream | flux care poate citi și scrie |
Un flux este legătura dintre program și fișier. Operatorul >> transferă date
dintr-un flux de intrare în variabile, iar operatorul << transferă date din
variabile în fluxul de ieșire.
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
În locul numelor fin și fout se pot folosi alți identificatori. Important
este ca fluxul de intrare să fie declarat cu ifstream, iar cel de ieșire cu
ofstream.
Deschiderea și verificarea
Fișierul se poate deschide chiar la declarare:
ifstream fin("date.in");
ofstream fout("date.out");
Se poate deschide și ulterior, cu funcția open:
ifstream fin;
fin.open("date.in");
După deschidere trebuie verificat dacă operația a reușit. Expresia fluxului poate fi folosită într-o condiție:
ifstream fin("date.in");
if (!fin) {
return 1;
}
Un fișier de intrare poate lipsi, poate avea un nume greșit sau poate să nu poată fi citit. Dacă programul continuă să citească dintr-un flux care nu s-a deschis, rezultatul nu este unul sigur.
Citirea cu operatorul >>
Operatorul >> citește următoarea valoare și ignoră spațiile, tabulatoarele și
trecerile la rând nou de la început:
int x;
fin >> x;
El se folosește pentru numere și pentru cuvinte:
int n;
fin >> n;
for (int i = 0; i < n; i++) {
int x;
fin >> x;
}
Pentru un șir de caractere în stil C++, >> citește numai până la primul
spațiu. Dacă fișierul conține linia Ana are mere, în variabila s ajunge
numai Ana. Pentru o linie întreagă se folosește getline.
Citirea până la sfârșitul fișierului
Forma sigură este cea în care operația de citire este scrisă chiar în condiția structurii repetitive:
int x;
while (fin >> x) {
// x este valid și poate fi prelucrat
}
Citirea evaluează fluxul ca adevărat cât timp a reușit să extragă o valoare. Când ajunge la sfârșitul fișierului sau întâlnește o valoare incompatibilă cu tipul variabilei, condiția devine falsă și execuția structurii repetitive se încheie.
Nu se scrie:
while (!fin.eof()) {
fin >> x;
// x poate conține încă valoarea citită la pasul anterior
}
eof() devine adevărat abia după ce o citire a încercat să treacă de sfârșitul
fișierului. De aceea această formă poate prelucra o valoare veche încă o dată.
Citirea unei linii întregi
Pentru a păstra și spațiile dintr-o linie se folosește getline:
#include <string>
string linie;
getline(fin, linie);
Citirea se oprește la caracterul de trecere la rând nou, iar acesta nu intră în
șir.
Dacă înainte s-a folosit >>, trecerea la rând nou rămasă în flux trebuie
eliminată:
int n;
fin >> n;
fin.ignore();
string linie;
getline(fin, linie);
Într-o problemă în care se citesc numai numere sau cuvinte separate prin spații,
>> este mai simplu și nu este nevoie de getline.
Scrierea în fișier
Operatorul << scrie în fișier exact ca în cazul lui cout:
int suma = 37;
fout << suma;
Se pot scrie mai multe valori și se pot adăuga spații sau treceri la rând:
fout << suma << '\n';
fout << x << ' ' << y;
Afișarea pe ecran și scrierea într-un fișier au aceeași formă, dar fluxul este diferit:
cout << rezultat; // ecran
fout << rezultat; // fișier
Modurile de deschidere
ifstream deschide, în mod obișnuit, fișierul pentru citire, iar ofstream
pentru scriere. Funcția open poate primi și un mod explicit:
| Mod | Semnificație |
|---|---|
ios::in | citire |
ios::out | scriere |
ios::app | scriere la sfârșitul fișierului |
ios::trunc | ștergerea conținutului vechi la deschidere |
ios::binary | transfer binar; nu se folosește pentru fișiere text |
ofstream fout("rezultat.txt", ios::out);
La deschiderea unui ofstream pentru scriere, conținutul vechi este, în mod
normal, înlocuit. Pentru adăugare la sfârșit:
ofstream fout("jurnal.txt", ios::app);
Închiderea fișierului
Fișierul se închide cu close:
fin.close();
fout.close();
Închiderea eliberează resursele și asigură scrierea în fișier a datelor aflate încă în zona tampon. Dacă un program folosește mai multe fișiere, fiecare trebuie închis după ultima operație asupra lui.
Model complet de citire și prelucrare
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream fin("date.in");
ofstream fout("date.out");
if (!fin || !fout)
return 1;
int x;
int suma = 0;
while (fin >> x) {
suma += x;
}
fout << suma;
fin.close();
fout.close();
return 0;
}
Programul citește toate numerele din date.in, le adună fără să memoreze
șirul și scrie suma în date.out. Pentru n valori, timpul este O(n), iar
memoria suplimentară este O(1).
Materialul acesta se citește pe educamp.ro și nu se tipărește.
S-a încheiat minutul de citit liber.
Ce cuprinde subcapitolul
- Ce trebuie făcut, în ordine
- Fișier de intrare și fișier de ieșire
- Operații cu fișiere în C++ și Python
- Transferul datelor între două fișiere
- Fișier gol și date invalide
- Greșeli frecvente la examen
- Schema de rezolvare
Continuă lectura ca și cursant
Cel puțin un subcapitol din fiecare capitol este disponibil gratuit și integral. Pentru a citi toate celelalte subcapitole ale disciplinei, te înscrii la cursul de pregătire.
Te înscrii, alegi în cont când începe cursul și plătești prima lună prin transfer bancar. Pentru a vedea mai întâi cum este prezentată materia, poți reveni la primul subcapitol al capitolului.
Acces la suportul de curs
25 RON / lună, fără ședințe
Ce cuprinde:
- Acces la toate lecțiile disponibile
- Suport de curs pentru tematica științifică și metodică
- Exemple, explicații și exerciții
- Acces la materialele noi adăugate pe platformă
- Posibilitatea de a adresa întrebări
Poți alege și variante cu ședințe online, în grup sau individuale. Le vezi pe pagina cursului.
Ai întrebări sau o problemă? Scrie-mi pe WhatsApp, la 0745 874 576.
Surse (4)
- Cerchez, E., Șerban, M., „Programarea în limbajul C/C++ pentru liceu”, Editura Polirom, Iași, 2005
- „Informatică. Manual pentru clasa a IX-a”, Editura Didactică și Pedagogică, București
- „Informatică. Manual pentru clasa a XI-a”, Editura Didactică și Pedagogică, București
- „Tutorialul de Python”, documentația oficială a limbajului Python, https://docs.python.org/ro/3/tutorial/inputoutput.html