Bun venit la cea mai importantă lecție din viața unui program! Dacă până acum am lucrat cu date “pe viu” în memorie, acum învățăm cum să le salvăm și să le recuperăm, exact cum faci cu pozele pe telefon sau documentele pe calculator!
1. Ce sunt Fișierele Text? “Caietul de Notițe” al Programului
Analogie cu viața reală:
- Memoria RAM = tabla cu cretă (se șterge când dai drumul la curent)
- Fișierul text = caiet în care scrii (rămâne și după ce închizi calculatorul)
Cum gândește calculatorul:
Calculatorul vede:
F I Ș I E R . T X T
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
01000110 01001001 ...
Dar NOI îl vedem ca pe text normal!
2. Tipuri de Acces: “Cum Citești o Carte”
A. Acces Secvențial – “Cititul Pagină cu Pagină”
Imaginează-ți o casetă audio:
- Pornesti de la început
- Asculți piesa 1, apoi 2, apoi 3…
- NU poți sări direct la piesa 3 fără să treci prin 1 și 2
#include <iostream>
#include <fstream> // BIBLIOTECA MAGICĂ pentru fișiere!
using namespace std;
int main() {
cout << "=== ACCES SECVENȚIAL ===\n";
cout << "(ca o casetă audio)\n\n";
// Scriere secvențială
ofstream caseta_out("casetta.txt");
caseta_out << "Piesa 1: Hello World\n";
caseta_out << "Piesa 2: Salut Romania\n";
caseta_out << "Piesa 3: La revedere\n";
caseta_out.close(); // ÎNCHIDE întotdeauna caseta!
// Citire secvențială
ifstream caseta_in("casetta.txt");
string linie;
cout << "Ascult caseta de la început:\n";
while(getline(caseta_in, linie)) {
cout << "▶ " << linie << endl;
}
caseta_in.close();
return 0;
}
B. Acces Aleator (Random Access) – “DVD-ul cu Butoane”
Imaginează-ți un DVD:
- Poți sări la scena 5 direct
- Poți derula înainte/înapoi
- Ai butoane de control
#include <iostream>
#include <fstream>
using namespace std;
int main() {
cout << "=== ACCES ALEATOR ===\n";
cout << "(ca un DVD cu telecomanda)\n\n";
// Creăm un "DVD" cu scene
fstream dvd("filmul_meu.txt", ios::out);
dvd << "Scena 1: Începutul\n";
dvd << "Scena 2: Acțiunea\n";
dvd << "Scena 3: Climaxul\n";
dvd << "Scena 4: Sfârșitul\n";
dvd.close();
// Acum citim ca la DVD!
fstream dvd_in("filmul_meu.txt", ios::in);
// Sărim direct la scena 3
// Găsim unde începe fiecare scenă...
dvd_in.seekg(0, ios::end); // Mergem la sfârșit
int lungime = dvd_in.tellg(); // Aflăm lungimea totală
cout << "Lungimea filmului: " << lungime << " caractere\n\n";
// Mergem înapoi la începutul scenei 3
dvd_in.seekg(30, ios::beg); // Sărim la caracterul 30
string scena3;
getline(dvd_in, scena3);
cout << "Am sărit la: " << scena3 << endl;
dvd_in.close();
return 0;
}
3. Biblioteca <fstream> – “Cutia cu Instrumente”
Cele 3 instrumente principale:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
cout << "=== INSTRUMENTELE DIN <fstream> ===\n\n";
// 1. OFSTREAM - "Scriitorul"
// Doar SCRIE în fișier
cout << "1. ofstream - SCRIITORUL:\n";
ofstream scriitor("jurnal.txt");
if(scriitor.is_open()) { // VERIFICĂ dacă s-a deschis
scriitor << "Azi am învățat C++\n";
scriitor << "Este foarte interesant!\n";
scriitor.close();
cout << " ✓ Am scris în jurnal\n";
} else {
cout << " ✗ Nu pot deschide jurnalul\n";
}
// 2. IFSTREAM - "Cititorul"
// Doar CITEȘTE din fișier
cout << "\n2. ifstream - CITITORUL:\n";
ifstream cititor("jurnal.txt");
if(cititor.is_open()) {
string linie;
cout << " Conținutul jurnalului:\n";
while(getline(cititor, linie)) {
cout << " • " << linie << endl;
}
cititor.close();
}
// 3. FSTREAM - "Actorul Universal"
// Poate atât CITI cât și SCRIE
cout << "\n3. fstream - ACTORUL UNIVERSAL:\n";
fstream universal("notite.txt", ios::out | ios::in | ios::app);
if(universal.is_open()) {
// Scrie ceva
universal << "Notita 1: Cumpar lapte\n";
// Citește ce am scris
universal.seekg(0); // Înapoi la început
string continut;
getline(universal, continut);
cout << " Am citit: " << continut << endl;
universal.close();
}
return 0;
}
4. Moduri de Deschidere – “Cheile” pentru Fișiere
#include <iostream>
#include <fstream>
using namespace std;
int main() {
cout << "=== MODURILE DE DESCHIDERE ===\n";
cout << "(diferite 'chei' pentru diferite uși)\n\n";
// ios::out - "Scrie peste tot"
// Dacă fișierul există, îl șterge și începe de la 0
ofstream out("test_out.txt", ios::out);
out << "Scriere cu ios::out\n";
out.close();
// ios::app - "Adaugă la sfârșit"
// Ca să adaugi la un jurnal existent
ofstream app("test_app.txt", ios::app);
app << "Linie 1\n";
app << "Linie 2\n"; // Se adaugă după Linie 1
app.close();
// ios::in - "Doar citire"
// Doar citești, nu poți modifica
ifstream in("test_app.txt", ios::in);
// ... citește
in.close();
// ios::ate - "Sari la Sfârșit"
// Deschide și sări direct la final
fstream ate("test_app.txt", ios::ate | ios::in);
ate << "Linie adăugată la sfârșit\n";
ate.close();
// ios::binary - "Mod binar"
// Pentru imagini, sunete, executabile
// (nu pentru text normal)
cout << "Moduri comune combinate:\n";
cout << "• ios::out | ios::app - adaugă la sfârșit\n";
cout << "• ios::in | ios::out - citește și scrie\n";
cout << "• ios::binary | ios::in - citire binară\n";
return 0;
}
5. Cum Gândește Calculatorul cu Fișierele?
Imaginează-ți un cărăuș cu cărți:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
cout << "=== CĂRĂUȘUL DE DATE ===\n\n";
// 1. DESCHIDEREA - "Deschid ușa depozitului"
fstream depozit("depozit.txt", ios::out);
if(!depozit) { // Verificare rapidă
cout << "Ups! Nu pot deschide depozitul!\n";
return 1;
}
// 2. SCRIEREA - "Pun cutii în depozit"
cout << "Pun în depozit:\n";
cout << " - Cutia 'Mere': 10kg\n";
cout << " - Cutia 'Pere': 5kg\n";
cout << " - Cutia 'Banane': 3kg\n\n";
depozit << "Mere 10\n";
depozit << "Pere 5\n";
depozit << "Banane 3\n";
// 3. ÎNCHIDEREA - "Închid ușa și încui"
depozit.close();
cout << "✓ Depozitul este închis și securizat!\n\n";
// 4. REDESCHIDEREA - "Vin a doua zi la depozit"
cout << "A doua zi...\n";
depozit.open("depozit.txt", ios::in);
// 5. CITIREA - "Verific ce am în depozit"
cout << "Verific inventarul:\n";
string produs;
int cantitate;
while(depozit >> produs >> cantitate) {
cout << " • " << produs << ": " << cantitate << "kg\n";
}
depozit.close();
// 6. ADAUGARE - "Mai aduc marfă"
cout << "\nMai aduc mere...\n";
ofstream adauga("depozit.txt", ios::app); // APPEND!
adauga << "Mere 5\n"; // +5kg mere
adauga.close();
cout << "✓ Am adăugat 5kg mere\n";
return 0;
}
6. Lucrul cu Linii Complete
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
cout << "=== JURNALUL ELEVULUI ===\n\n";
// Scriere cu getline
ofstream jurnal("jurnal.txt");
cout << "Scrie în jurnal (scrie 'stop' pe linie nouă pentru a încheia):\n";
string intrare;
while(true) {
cout << "> ";
getline(cin, intrare);
if(intrare == "stop") {
break;
}
jurnal << intrare << endl;
}
jurnal.close();
// Citire cu getline
cout << "\n--- CITIRE JURNAL ---\n";
ifstream citire_jurnal("jurnal.txt");
string linie;
int numar_linie = 1;
while(getline(citire_jurnal, linie)) {
cout << numar_linie << ". " << linie << endl;
numar_linie++;
}
citire_jurnal.close();
return 0;
}
7. Verificări și Erori – “Sistemul de Alarmă”
#include <iostream>
#include <fstream>
using namespace std;
int main() {
cout << "=== SISTEMUL DE VERIFICARE ===\n\n";
// Încerc să deschid un fișier care NU există
ifstream fantoma("fisier_care_nu_exista.txt");
cout << "1. Verific existența:\n";
if(!fantoma) {
cout << " ✗ Fișierul nu există!\n";
cout << " (Calculatorul zice: 'Nu-l găsesc, boss!')\n";
}
cout << "\n2. Verific dacă e deschis:\n";
if(!fantoma.is_open()) {
cout << " ✗ Nu e deschis (normal, nu există!)\n";
}
cout << "\n3. Verific sfârșitul fișierului (eof):\n";
ifstream existent("existent.txt");
if(existent) {
string temp;
while(!existent.eof()) { // Cat timp NU am ajuns la End Of File
getline(existent, temp);
cout << " Am citit: " << temp << endl;
}
cout << " ✓ Am ajuns la sfârșitul fișierului\n";
}
cout << "\n4. Verificări rapide:\n";
cout << " • if(fisier) - fișierul e bun\n";
cout << " • fisier.good() - totul e în regulă\n";
cout << " • fisier.fail() - ceva n-a mers bine\n";
cout << " • fisier.bad() - eroare gravă\n";
cout << " • fisier.eof() - am ajuns la sfârșit\n";
return 0;
}
8. Exemplu Complex: “Agenda Telefonică”
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Contact {
string nume;
string telefon;
string email;
};
int main() {
cout << "=== AGENDA TELEFONICĂ DIGITALĂ ===\n\n";
// Meniu principal
int optiune;
do {
cout << "\n=== MENIU ===\n";
cout << "1. Adaugă contact\n";
cout << "2. Vezi toate contactele\n";
cout << "3. Caută contact\n";
cout << "4. Ieșire\n";
cout << "Alege: ";
cin >> optiune;
cin.ignore(); // Important!
switch(optiune) {
case 1: {
// ADAUGARE CONTACT
Contact nou;
cout << "\n--- ADAUGĂ CONTACT ---\n";
cout << "Nume: ";
getline(cin, nou.nume);
cout << "Telefon: ";
getline(cin, nou.telefon);
cout << "Email: ";
getline(cin, nou.email);
// Scrie în fișier (adaugă la sfârșit)
ofstream agenda("agenda.txt", ios::app);
if(agenda.is_open()) {
agenda << nou.nume << ","
<< nou.telefon << ","
<< nou.email << endl;
agenda.close();
cout << "✓ Contact salvat!\n";
} else {
cout << "✗ Eroare la salvare!\n";
}
break;
}
case 2: {
// AFIȘARE TOATE CONTACTELE
cout << "\n--- LISTA CONTACTE ---\n";
ifstream agenda("agenda.txt");
if(agenda.is_open()) {
string linie;
int nr = 1;
while(getline(agenda, linie)) {
// Găsește virgulele
size_t virgula1 = linie.find(',');
size_t virgula2 = linie.find(',', virgula1 + 1);
if(virgula1 != string::npos && virgula2 != string::npos) {
string nume = linie.substr(0, virgula1);
string telefon = linie.substr(virgula1 + 1, virgula2 - virgula1 - 1);
string email = linie.substr(virgula2 + 1);
cout << nr << ". " << nume << endl;
cout << " Tel: " << telefon << endl;
cout << " Email: " << email << endl;
cout << endl;
nr++;
}
}
agenda.close();
if(nr == 1) {
cout << "Agenda este goală!\n";
}
} else {
cout << "Nu am găsit agenda!\n";
}
break;
}
case 3: {
// CĂUTARE CONTACT
cout << "\n--- CĂUTARE CONTACT ---\n";
cout << "Nume de căutat: ";
string cauta;
getline(cin, cauta);
ifstream agenda("agenda.txt");
bool gasit = false;
if(agenda.is_open()) {
string linie;
while(getline(agenda, linie)) {
// Extrage numele (prima parte până la virgulă)
size_t virgula = linie.find(',');
string nume = linie.substr(0, virgula);
// Verifică dacă se potrivește
if(nume.find(cauta) != string::npos) {
cout << "\n✓ CONTACT GĂSIT:\n";
cout << "Nume: " << nume << endl;
// Extrage telefonul
size_t virgula2 = linie.find(',', virgula + 1);
string telefon = linie.substr(virgula + 1, virgula2 - virgula - 1);
cout << "Tel: " << telefon << endl;
// Extrage email
string email = linie.substr(virgula2 + 1);
cout << "Email: " << email << endl;
gasit = true;
}
}
agenda.close();
if(!gasit) {
cout << "✗ Nu am găsit contactul '" << cauta << "'\n";
}
}
break;
}
case 4:
cout << "\nLa revedere! Agenda a fost salvată.\n";
break;
default:
cout << "\n✗ Opțiune invalidă!\n";
}
} while(optiune != 4);
return 0;
}
9. Reguli de Aur pentru Fișiere Text
REGULA 1: Închide întotdeauna fișierul!
// GREȘIT
ofstream fisier("test.txt");
fisier << "ceva";
// ... programul se încheie fără close()
// CORECT
ofstream fisier("test.txt");
fisier << "ceva";
fisier.close(); // ÎNCHIDE!
REGULA 2: Verifică dacă s-a deschis!
ofstream fisier("test.txt");
if(fisier.is_open()) { // SAU: if(fisier)
// ... operatii
} else {
cout << "Eroare la deschidere!";
}
REGULA 3: Folosește ios::app pentru adăugare
// Dacă vrei să adaugi, NU să înlocuiești:
ofstream fisier("jurnal.txt", ios::app); // APPEND!
REGULA 4: Șterge enter-ul cu cin.ignore()
int varsta;
string nume;
cout << "Varsta: ";
cin >> varsta;
cin.ignore(); // ȘTERGE ENTER-UL RĂMAS!
cout << "Nume: ";
getline(cin, nume); // Acum merge bine!
10. Exercițiu Final: “Jocul Memoriei”
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
using namespace std;
int main() {
cout << "=== JOCUL MEMORIEI ===\n";
cout << "Scrie ce vrei, iar calculatorul își va aminti!\n\n";
// Deschide sau creează fișierul
fstream memoria("memorie.txt", ios::in | ios::out | ios::app);
if(!memoria.is_open()) {
// Dacă nu există, îl creează
memoria.open("memorie.txt", ios::out);
memoria << "=== JOCUL MEMORIEI ===\n";
memoria.close();
memoria.open("memorie.txt", ios::in | ios::out | ios::app);
}
// Citește ce era deja
cout << "AMINTIRILE ANTERIOARE:\n";
cout << "----------------------\n";
memoria.seekg(0); // Mergi la început
string linie;
while(getline(memoria, linie)) {
cout << linie << endl;
}
// Adaugă amintire nouă
cout << "\n--- ADAUGĂ O AMINTIRE ---\n";
cout << "Scrie ceva (scrie 'gata' pentru a încheia):\n";
string amintire;
time_t acum = time(0);
char* data = ctime(&acum);
memoria << "\n[" << data << "]\n";
while(true) {
cout << "> ";
getline(cin, amintire);
if(amintire == "gata") {
break;
}
memoria << "- " << amintire << endl;
}
memoria << "----------------------\n";
memoria.close();
cout << "\n✓ Am salvat amintirea!\n";
cout << "Data viitoare când vei rula programul,\n";
cout << "vei vedea și amintirile vechi!\n";
return 0;
}
CONCLUZIE: De ce sunt importante fișierele?
- Persistență – Datele rămân și după ce închizi programul
- Partajare – Poți trimite fișierul altcuiva
- Backup – Poți salva progresul în jocuri/programe
- Logging – Programele “țin jurnal” cu ce fac
Gândiți-vă la fișiere ca la:
- Jurnal personal pentru program
- Cutie de valori pentru date importante
- Memorie externă pentru calculator
Ultimul sfat:
// Întotdeauna tratează fișierele cu grijă!
// E ca și cum ai avea grijă de un caiet prețios.
// Verifică, închide, și fii atent la erori!
// Happy coding! 📁✨
Leave a Reply