📁 Fișiere

Capitolul 8 — ifstream, ofstream, fstream, freopen, citire/scriere, prelucrare fișiere și probleme BAC

FișierefstreamifstreamofstreamEOF
📖 12 min
0
📂

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++;
}
🎮

Demo interactiv — Fluxul fișierelor

Vizualizează cum datele circulă între fișiere și program. Scenariul: date.in → program C++ → date.out.

📥 date.in (Intrare)
3 1 4 1 5 9 2 6
→
🖥️ Program C++
while(fin >> x)
s += x;
→
📤 date.out (Ieșire)
Aștept procesare...
Normal
La BAC: datele sunt întotdeauna citite din fișier cu ifstream și scrise în fișier cu ofstream. Exersează while (fin >> x) — cel mai folosit idiom!
🧩

Probleme rezolvate — fișiere

5 probleme practice cu ifstream / ofstream / freopen.

1 Copiere fișier Ușor
Citește toate numerele din date.in și scrie-le în date.out (separate prin spațiu).
date.in:
3 1 4 1 5 9 2 6
date.out:
3 1 4 1 5 9 2 6
💡 Vezi soluția
ifstream f("date.in");
ofstream g("date.out");
int x;
while (f >> x) g << x << ' ';
f.close(); g.close();

Idiom esențial: while (f >> x) citește până la sfârșitul fișierului (EOF).

2 Suma și media numerelor din fișier Ușor
Citește din numere.in oricâte numere (nu știi câte). Scrie în numere.out suma și media (2 zecimale).
numere.in:
10 20 30 40
numere.out:
100 25.00
💡 Vezi soluția
ifstream f("numere.in");
ofstream g("numere.out");
long long s = 0; int n = 0, x;
while (f >> x) { s += x; n++; }
g << s << ' ' << fixed << setprecision(2) << (double)s / n;

Atenție: dacă fișierul poate fi gol (n = 0), trebuie tratat separat ca să eviți împărțirea la 0.

3 Numără cuvinte pe linie Mediu
Pentru fiecare linie din text.in, scrie în text.out numărul de cuvinte de pe acea linie.
text.in:
Salut lume
Astazi e o zi frumoasa
C++
text.out:
2
5
1
💡 Vezi soluția
ifstream f("text.in");
ofstream g("text.out");
string linie, cuv;
while (getline(f, linie)) {
    stringstream ss(linie);
    int cnt = 0;
    while (ss >> cuv) cnt++;
    g << cnt << '\n';
}

Cheia: getline citește linia, apoi stringstream o sparge în cuvinte pe baza spațiilor.

4 Maxim și poziție Mediu
Citește numerele din v.in. Afișează în v.out valoarea maximă și poziția (indexată de la 1) primei apariții.
v.in:
3 7 1 7 5
v.out:
7 2
💡 Vezi soluția
ifstream f("v.in");
ofstream g("v.out");
int x, idx = 0, pos = 0;
int mx = INT_MIN;
while (f >> x) {
    idx++;
    if (x > mx) { mx = x; pos = idx; }
}
g << mx << ' ' << pos;

Detaliu: folosim x > mx (strict) ca să reținem doar prima apariție a maximului.

5 Filtrare numere prime în alt fișier Dificil
Citește numere din in.txt. Scrie în prime.txt doar numerele prime, separate prin spațiu.
in.txt:
10 7 4 11 9 13 1 2
prime.txt:
7 11 13 2
💡 Vezi soluția
bool prim(int n) {
    if (n < 2) return false;
    for (int d = 2; d*d <= n; d++)
        if (n % d == 0) return false;
    return true;
}
int main() {
    ifstream f("in.txt");
    ofstream g("prime.txt");
    int x;
    while (f >> x)
        if (prim(x)) g << x << ' ';
}

Pattern frecvent: citește → filtrează cu o funcție auxiliară → scrie în fișier de ieșire.

⚠️ La BAC: denumirea fișierelor e specificată în enunț. Citește-o cu atenție — o tipăritură greșită înseamnă 0 puncte!
📝

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
💪

Exerciții interactive — testează cunoștințele