📁 Fișiere

Capitolul 7 — 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++;
}
📝

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