📂
Deschiderea și închiderea fișierelor
📁 Analogie: Fișierele = Caiete de temă
Un fișier text este ca un caiet: îl deschizi (fopen), citești sau scrii în el, apoi îl închizi (fclose). Dacă uiți să-l închizi, datele scrise pot fi pierdute!
În C++ folosim fluxuri din antetul <fstream> pentru a lucra cu fișiere text.
#include <fstream> using namespace std; // ifstream — doar citire ifstream fin("date.in"); if (!fin) { cout << "Eroare: fisierul nu exista!"; return 1; } // ofstream — doar scriere (creează sau suprascrie fișierul) ofstream fout("date.out"); // ofstream cu append (adaugă la final) ofstream fapp("log.txt", ios::app); // fstream — citire și scriere fstream fs("date.txt", ios::in | ios::out); // Închiderea explicită (opțional — se face și automat la ieșire din funcție) fin.close(); fout.close();
ifstream
Input File Stream — citire din fișier
ofstream
Output File Stream — scriere în fișier
fstream
File Stream — citire și scriere
📥
Citire din fișier
Citire token cu token (numere, cuvinte)
ifstream fin("date.in"); int n, x; fin >> n; for (int i = 1; i <= n; i++) { fin >> x; // procesare x } fin.close();
Citire linie cu linie
ifstream fin("text.txt"); string linie; while (getline(fin, linie)) { // procesare linie cout << linie << endl; }
Citire până la EOF (fără a ști numărul de elemente)
ifstream fin("numere.in"); int x; while (fin >> x) { // procesare x până la capătul fișierului }
Citire matrice din fișier
ifstream fin("matrice.in"); int n, m, a[101][101]; fin >> n >> m; for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) fin >> a[i][j];
📤
Scriere în fișier
ofstream fout("rezultat.out"); // Scriere numere fout << n << endl; for (int i=1; i<=n; i++) fout << v[i] << " "; fout << endl; // Scriere formatată — aliniere la câmpuri fixe #include <iomanip> fout << setw(10) << setfill('0') << nr; // ex: 0000000042 fout << fixed << setprecision(2) << 3.14159; // 3.14 fout.close();
Buna practică: Apelați întotdeauna
fout.close() sau lăsați obiectul să iasă din scope — asigurați că datele sunt scrise pe disc (flush).
🔀
freopen — redirectare I/O (stil BAC olimpiadă)
La olimpiadele de informatică, problemele cer citire din problema.in și scriere în problema.out. Cel mai simplu mod: redirectăm stdin/stdout cu freopen.
#include <cstdio> // freopen #include <iostream> using namespace std; int main() { freopen("suma.in", "r", stdin); // cin va citi din suma.in freopen("suma.out", "w", stdout); // cout va scrie în suma.out int n, s = 0, x; cin >> n; for (int i=1; i<=n; i++) { cin >> x; s += x; } cout << s; return 0; }
Avantaj freopen: Puteți folosi
cin/cout exact ca la citirea de la tastatură. Nu trebuie să schimbați restul codului.
Alternativă cu ifstream/ofstream: Înlocuiți
cin cu fin și cout cu fout. Ambele variante sunt acceptate la BAC.
🔧
Prelucrarea fișierelor — exemple complete
Exemplu complet: citire din fișier, prelucrare, scriere
#include <fstream> using namespace std; int main() { ifstream fin("maxim.in"); ofstream fout("maxim.out"); int n; fin >> n; int maxim, x; fin >> maxim; for (int i=2; i<=n; i++) { fin >> x; if (x > maxim) maxim = x; } fout << maxim; fin.close(); fout.close(); return 0; }
Copiere fișier text (linie cu linie)
ifstream fin("sursa.txt"); ofstream fout("copie.txt"); string linie; while (getline(fin, linie)) fout << linie << "\n";
Numărarea liniilor și cuvintelor dintr-un fișier
ifstream fin("text.txt"); int nrLinii = 0, nrCuvinte = 0; string linie, cuvant; while (getline(fin, linie)) { nrLinii++; stringstream ss(linie); while (ss >> cuvant) nrCuvinte++; }
📝
Probleme tip BAC — fișiere
Problemă 1 (BAC clasic): Fișierul
sir.in conține pe prima linie un număr natural n, iar pe a doua linie n numere întregi separate prin spații. Scrieți în sir.out suma elementelor pare și produsul elementelor impare.
Soluție:
#include <fstream> using namespace std; int main() { ifstream fin("sir.in"); ofstream fout("sir.out"); int n, x, sumPar = 0, prodImpar = 1; fin >> n; for (int i=1; i<=n; i++) { fin >> x; if (x % 2 == 0) sumPar += x; else prodImpar *= x; } fout << "Suma pare: " << sumPar << endl; fout << "Prod impar: " << prodImpar; return 0; }
Problemă 2: Fișierul
text.in conține un text pe mai multe linii. Scrieți în text.out fiecare cuvânt de lungime maximă din text (câte unul pe linie).
Soluție:
#include <fstream> #include <vector> #include <sstream> using namespace std; int main() { ifstream fin("text.in"); ofstream fout("text.out"); vector<string> toate; string linie, cuvant; int lenMax = 0; while (getline(fin, linie)) { stringstream ss(linie); while (ss >> cuvant) { toate.push_back(cuvant); if ((int)cuvant.size() > lenMax) lenMax = cuvant.size(); } } for (auto &w : toate) if ((int)w.size() == lenMax) fout << w << endl; return 0; }
Resurse utile BAC informatică:
pbinfo.ro — probleme și soluții BAC • infoarena.ro — arhivă olimpiadă • cplusplus.com/reference/fstream — referință fstream
pbinfo.ro — probleme și soluții BAC • infoarena.ro — arhivă olimpiadă • cplusplus.com/reference/fstream — referință fstream
💪