Bazele programării în C++

Fișiere text în C++: citire, scriere și EOF

Fișierele text păstrează date între două rulări ale programului. În C++ folosești `std::ifstream` pentru citire și `std::ofstream` pentru scriere, din antetul `<fstream>`. Un flux seamănă cu `cin` sau `cout`, dar este legat de un fișier, nu de tastatură ori ecran.

Fișierele text păstrează date între două rulări ale programului. În C++ folosești std::ifstream pentru citire și std::ofstream pentru scriere, din antetul <fstream>. Un flux seamănă cu cin sau cout, dar este legat de un fișier, nu de tastatură ori ecran.

Înainte să alegi numele fișierelor, citește cerința evaluatorului. Un program corect pentru consolă poate să nu producă ieșirea cerută dacă încearcă să scrie în altă parte. Exemplele de aici rulează local și folosesc explicit date.in și date.out.

Cum funcționează

Constructorul deschide fișierul. Verificarea if (!fin) detectează eșecul deschiderii; programul nu trebuie să continue cu variabile neinițializate. Pentru ieșire, deschiderea obișnuită prin ofstream înlocuiește conținutul anterior. Modul std::ios::app adaugă la final, dar nu este potrivit când fiecare rulare trebuie să producă un rezultat nou.

Dacă numărul valorilor nu este precizat, condiția corectă este while (fin >> x). Mai întâi se încearcă extragerea, apoi corpul buclei folosește valoarea obținută. while (!fin.eof()) verifică o stare care poate deveni adevărată abia după o citire eșuată și riscă să prelucreze încă o dată valoarea veche.

Calea relativă se rezolvă față de directorul de lucru al procesului, care nu coincide obligatoriu cu folderul sursei. Într-un IDE, verifică directorul de execuție. Numele și extensia trebuie să fie exacte. La ieșirea din domeniul lor, obiectele flux închid fișierele; închiderea explicită este utilă dacă vrei să verifici o eroare de scriere înainte de terminarea programului.

Exemplu urmărit pas cu pas

Presupunem că date.in conține 4 -2 7. Suma pornește de la zero. Cele trei citiri reușite produc pe rând 4, 2 și 9. A patra citire nu găsește un număr și corpul buclei nu se execută. În date.out apare 9 urmat de trecerea la linia următoare.

Un fișier gol produce suma zero. Un fișier care conține 4 text 7 este diferit: citirea se oprește la cuvântul nevalid, iar programul de mai jos raportează date incorecte prin codul de ieșire. Nu confundăm sfârșitul normal al datelor cu un token care nu poate fi interpretat ca număr.

Implementare C++17

#include <fstream>
int main() {
    std::ifstream fin("date.in");
    if (!fin)
        return 1;
    long long x, suma = 0;
    while (fin >> x)
        suma += x;
    if (!fin.eof())
        return 2;
    std::ofstream fout("date.out");
    if (!fout)
        return 3;
    fout << suma << '\n';
    fout.close();
    return fout ? 0 : 4;
}

De ce funcționează și cât costă

După fiecare extragere reușită, suma este exact suma numerelor citite până atunci. Inițial afirmația este adevărată pentru mulțimea vidă; adăugarea următorului număr o păstrează. La sfârșitul valid al fișierului au fost incluse toate numerele.

Pentru n numere, timpul este O(n), iar memoria suplimentară este O(1). Presupunem cel mult 100000 de întregi cu modulul cel mult un miliard, astfel încât suma încape în long long. Limita nu decurge automat din faptul că fluxul poate citi oricâte valori.

Greșeli frecvente

Nu afișa explicații în fișierul de răspuns când evaluatorul cere doar numere. Nu testa existența fișierului printr-o citire care consumă primul element. Verifică și fluxul de ieșire: un director fără drept de scriere poate împiedica salvarea, chiar dacă algoritmul este corect.

Exersează

Cum modifici programul pentru a afișa și numărul valorilor negative? Verifică un fișier fără numere negative și un fișier gol.

Rezolvare explicată: Inițializezi un contor cu zero și îl crești numai după o extragere reușită pentru care x este negativ. Fișierul gol păstrează atât suma, cât și contorul la zero.

Continuă să înveți

Recapitulează citirea și afișarea, buclele și sumele.

Întrebări frecvente

Care este diferența dintre ifstream și ofstream?

ifstream citește dintr-un fișier, iar ofstream scrie într-un fișier. Ambele sunt fluxuri, dar direcția transferului diferă. Pentru citire folosești operatorul >>, iar pentru scriere operatorul <<.

De ce nu se recomandă while (!fin.eof())?

Starea EOF se actualizează după o încercare de citire. Verificarea înaintea extragerii poate permite încă o iterație cu valoarea precedentă. Testează chiar extragerea: while (fin >> x).

Unde trebuie pus fișierul de intrare?

Pentru o cale relativă, în directorul de lucru al programului. IDE-ul poate configura acest director separat de folderul în care ai salvat sursa C++.

Cum citesc o linie care conține spații?

Folosește getline pe fluxul de fișier, împreună cu un std::string, sau metoda getline a fluxului pentru char[]. Operatorul >> se oprește la separatorii de spațiu.

Pot înlocui cin și cout cu fișiere la orice problemă?

Numai dacă respecți interfața cerută de problemă. Citirea dintr-un fișier local și citirea de la intrarea standard sunt modalități diferite de a furniza datele evaluatorului.

Un pas mai departe

Se încarcă progresul…

Exersează cu o problemă →