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.
Un fișier text este o succesiune de caractere păstrată pe un suport extern. 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
Un fișier de intrare este citit de program. Un fișier de ieșire este scris de program. 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.
Operații cu fișiere în C++ și Python
Fișiere text în C++
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 alte identificatoare. 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 să pui operația de citire chiar în condiția buclei:
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 bucla se oprește.
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 trecerea la rând nou, iar aceasta 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 se asigură că datele scrise în buffer ajung în fișier. 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.
Cursul cuprinde suportul de curs publicat până acum, care se completează capitol cu capitol, și două întâlniri de câte două ore în fiecare lună. Prima săptămână este gratuită, fără plată și fără card. Dacă vrei să vezi mai întâi cum este prezentată materia, poți reveni la primul subcapitol al capitolului.
Începe săptămâna gratuită Sunt cursant — login
Află când publicăm materiale noi
Materia este publicată treptat, capitol cu capitol. Înscrie-te pentru a primi un e-mail atunci când apare un capitol nou de informatică.
Nu am putut înregistra adresa. Verifică e-mailul și materia aleasă, apoi încearcă din nou.
Surse
- 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