Lucrul cu fișiere în C++ la atestatul de informatică
Citirea din fișiere text cu ifstream: matrici, șiruri de caractere, citire până la sfârșit, structuri și sortare după o valoare calculată — cu problemele de atestat în care apar.
15 din cele 40 de probleme de programare din sesiunea Dolj 2026 citesc datele dintr-un fişier.
Vestea bună: ifstream se folosește exact ca cin, iar odată ce știi cele trei moduri de
citire, partea de fişiere devine mecanică și te poți concentra pe logica problemei.
Scheletul de bază
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream f("date.in"); // deschidere
// ... citire cu f >> sau f.getline
f.close(); // inchidere
}
ifstream e „ruda" lui cin pentru fişiere. Tot ce știi despre cin >> funcționează identic cu
f >>. Diferă doar două lucruri: îl deschizi cu numele fişierului și îl închizi la final.
f.close() nu schimbă rezultatul la programe mici, dar e cerut de barem — scrie-l.
Atenție la sursa datelor. Multe enunțuri citesc datele principale din fişier, dar parametrii de la tastatură: liniile de interschimbat, cuvântul căutat. Sunt fluxuri separate —
f >>pentru fişier,cin >>pentru tastatură. Confuzia face programul să pară blocat.
Cele trei moduri de citire
Alegerea depinde de ce conține fişierul. E singura decizie reală pe care o iei.
1. Știi câte valori sunt
Formatul cel mai comun: prima linie spune cât urmează.
int n;
f >> n;
for (int i = 0; i < n; i++) f >> x[i];
Pentru matrici, n e dimensiunea și urmează două bucle imbricate:
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
f >> a[i][j];
Toate cele 9 probleme cu matrici folosesc acest tipar, cu fişierul mat.in. Detaliile de
parcurgere — linii, coloane, diagonale — sunt explicate pe pagina dedicată
matricilor.
2. Nu știi câte valori sunt
Când fişierul conține doar numere, fără un n la început, citești până se termină:
int n = 0;
while (f >> x[n]) n++;
Citirea returnează o valoare care devine false când nu mai are ce citi, deci bucla se oprește
singură. La final, n conține exact numărul de valori.
Același tipar funcționează și pe cuvinte, pentru că >> se oprește automat la spații:
while (f >> cuvant) { /* ... */ }
Probleme: valorile distincte și maximul · numerele distincte din două fişiere
Două fişiere? Citește-le în același vector, fără să resetezi
n. A doua buclă continuă de unde s-a oprit prima, iar de acolo ai o singură problemă.
3. Un rând întreg de text
Când fişierul conține o propoziție, cu spații și semne de punctuație:
char s[201];
f.getline(s, 201);
f >> s nu merge aici — s-ar opri la primul spațiu și ai prelua doar primul cuvânt.
Dimensiunea e 201 pentru „cel mult 200 de caractere": mai trebuie un loc pentru terminatorul
'\0', pe care C++ îl adaugă la final. Parcurgerea merge până la el, deci nu ai nevoie de lungime:
for (int i = 0; s[i] != '\0'; i++) { /* ... */ }
Probleme: numărul de vocale · aparițiile unui cuvânt
Lucrul cu caractere
Două tehnici acoperă majoritatea subiectelor cu text.
Conversia majusculă → minusculă, ca să nu scrii zece comparații:
if (c >= 'A' && c <= 'Z') c = c + 32;
Funcționează pentru că, în ASCII, literele mici sunt cu exact 32 de poziții după cele mari
('A' = 65, 'a' = 97). Verificarea intervalului e necesară — altfel strici cifrele și semnele de
punctuație.
Compararea cuvintelor se face cu strcmp, nu cu ==:
if (strcmp(cuvant, cautat) == 0) nr++;
== compară adresele din memorie, nu conținutul. Iar strcmp returnează 0 la egalitate, nu
1 — valoarea returnată e diferența în ordine alfabetică. Necesită #include <cstring>.
Citind cuvânt cu cuvânt cu
f >> cuvant, delimitarea se rezolvă singură:masininu va fi niciodată egal cusi. Dacă ai căuta subşiruri custrstr, ai număra și aparițiile din interiorul altor cuvinte.
Structuri și sortare după o valoare calculată
Când fişierul conține perechi de numere care formează o entitate — un număr complex, o fracție,
un elev — se folosește struct. Astfel datele rămân lipite la sortare.
Tiparul are trei câmpuri: datele originale plus valoarea după care sortezi, calculată o singură dată la citire:
struct Fractie {
int a, b; // datele din fisier
double valoare; // ce folosesti la comparatii
};
f >> fr[i].a >> fr[i].b;
fr[i].valoare = (double)fr[i].a / fr[i].b;
Conversia (double) e obligatorie. Între doi int, a / b dă împărțire întreagă: 1 / 4
ar fi 0, nu 0.25, iar sortarea ar ieși complet greșită.
Sortarea interschimbă structura întreagă, deci câmpurile nu se desperechează:
if (fr[j].valoare < fr[i].valoare) { // "<" crescator, ">" descrescator
Fractie aux = fr[i];
fr[i] = fr[j];
fr[j] = aux;
}
Probleme: ordonarea fracțiilor · modulele numerelor complexe
Formatarea numerelor reale
Când enunțul cere un anumit număr de zecimale:
#include <iomanip>
cout << fixed << setprecision(2) << x; // mereu 2 zecimale: 5.00
Se scrie o singură dată, înainte de buclă — setarea rămâne activă.
Diferența care contează: cu fixed numeri zecimalele; fără fixed, setprecision
numără cifrele semnificative, iar zecimalele nule dispar (5 în loc de 5.00). Citește exemplul
din enunț ca să vezi care formă se cere.
Greșeli care se repetă
f >> sîn loc def.getlinepentru text cu spații — se citește doar primul cuvântchar s[200]pentru „cel mult 200 de caractere" — lipsește locul terminatoruluicuvant == cautatîn loc destrcmp— compară adrese, nu conținutstrcmp(...) == 1— funcția returnează0la egalitate- Resetarea contorului între două fişiere citite în același vector
- Împărțirea fără
(double)la sortarea după o valoare calculată - Citirea parametrilor din fişier când enunțul îi cere de la tastatură
f.close()uitat — cerut de barem
Toate problemele din această categorie
Fiecare are rezolvare completă în C++, explicată pas cu pas.
- Modulele numerelor complexe dintr-un fișier, afișate în ordine descrescătoareProgramare
- Să se afişeze cel mai mare element din matrice şi poziţiile pe care apareProgramare
- Să se afişeze cel mai mic element din matrice şi poziţiile pe care apareProgramare
- Să se afişeze indicii coloanelor care au toate elementele impareProgramare
- Să se afişeze indicii liniilor care au toate elementele pareProgramare
- Să se afişeze maximele de pe fiecare linieProgramare
- Să se afişeze media aritmetică a elementelor strict pozitiveProgramare
- Să se afişeze numărul valorilor distincte din fişier şi valoarea maximăProgramare
- Să se afişeze, în ordine crescătoare, numerele distincte din cele două fişiereProgramare
- Să se calculeze şi să se afişeze media aritmetică a elementelor situate pe diagonala secundarăProgramare
- Să se determine numărul de vocale din şirProgramare
- Să se numere apariţiile unui cuvânt dat, citit de la tastatură, în textProgramare
- Să se ordoneze crescător fracţiile, afişând valorile zecimale ale lorProgramare
- Să se schimbe între ele două linii l1 şi l2, date de la tastaturăProgramare
- Verificarea dacă o matrice este simetrică față de diagonala principalăProgramare