fopen și fclose în C

Deschide un fișier pentru citire, scriere sau adăugare și returnează un FILE *; fclose îl închide și salvează datele rămase.

Sintaxă
#include <stdio.h>
FILE *fopen(const char *cale, const char *mod);
int fclose(FILE *f);

Ce face fopen și fclose

fopen deschide fișierul de la cale și returnează un pointer FILE *, pe care îl dai apoi funcțiilor de citire și scriere (fprintf, fgets, fread). Dacă fișierul nu poate fi deschis (nu există, nu ai drepturi), returnează NULL: verifică mereu.

Modul spune ce vrei să faci: "r" citire (fișierul trebuie să existe), "w" scriere (creează fișierul sau îl golește dacă există), "a" adăugare la final. Cu + ("r+", "w+", "a+") poți și citi, și scrie. Litera b ("rb", "wb") cere mod binar; pe Linux și macOS nu schimbă nimic, pe Windows oprește conversia lui \n. Din C11 există și "wx": eșuează dacă fișierul există deja.

fclose scrie pe disc ce a rămas în buffer și eliberează resursele. Fiecare fopen reușit trebuie să aibă un fclose; programele care deschid multe fișiere fără să le închidă ajung la limita sistemului.

Parametri

Parametru Descriere
cale Numele sau calea fișierului, relativă la directorul curent sau absolută.
mod "r", "w", "a", "r+", "w+", "a+", cu b opțional pentru binar și x (C11) pentru „doar dacă nu există”.
f La fclose: fișierul deschis cu fopen.

Ce returnează

fopen: un FILE * sau NULL la eroare (cu errno setat). fclose: 0 la succes, EOF la eroare.

Exemple

Exemplul 1: Scriere, apoi citire

Modul "w" creează fișierul note.txt în directorul curent. După fclose, îl deschidem cu "r" și îl citim rând cu rând.

#include <stdio.h>

int main(void) {
    FILE *f = fopen("note.txt", "w");
    if (f == NULL) {
        perror("note.txt");
        return 0;
    }
    fputs("Ana 9\n", f);
    fputs("Mihai 10\n", f);
    fclose(f);

    f = fopen("note.txt", "r");
    if (f == NULL) {
        perror("note.txt");
        return 0;
    }
    char rand[64];
    while (fgets(rand, sizeof rand, f) != NULL) {
        printf("citit: %s", rand);
    }
    fclose(f);
    return 0;
}

Rezultat

citit: Ana 9
citit: Mihai 10

Exemplul 2: Diferența dintre „w” și „a”

Fiecare deschidere cu "a" adaugă la final. Deschiderea cu "w" golește fișierul, așa că rămâne doar ultimul rând scris.

#include <stdio.h>

static void afiseaza(const char *cale) {
    FILE *f = fopen(cale, "r");
    if (f == NULL) return;
    int c;
    while ((c = fgetc(f)) != EOF) putchar(c);
    fclose(f);
}

int main(void) {
    const char *jurnal = "jurnal.txt";
    for (int i = 1; i <= 3; i++) {
        FILE *f = fopen(jurnal, "a");
        if (f == NULL) return 0;
        fprintf(f, "pornire %d\n", i);
        fclose(f);
    }
    puts("După trei deschideri cu \"a\":");
    afiseaza(jurnal);

    FILE *f = fopen(jurnal, "w");
    if (f == NULL) return 0;
    fputs("jurnal resetat\n", f);
    fclose(f);
    puts("După o deschidere cu \"w\":");
    afiseaza(jurnal);
    return 0;
}

Rezultat

După trei deschideri cu "a":
pornire 1
pornire 2
pornire 3
După o deschidere cu "w":
jurnal resetat

Exemplul 3: Fișier care nu există

La citirea unui fișier inexistent, fopen returnează NULL. strerror(errno) spune motivul în cuvinte.

#include <errno.h>
#include <stdio.h>
#include <string.h>

int main(void) {
    FILE *f = fopen("clienti-2025.csv", "r");
    if (f == NULL) {
        printf("Nu pot deschide fișierul: %s\n", strerror(errno));
        return 0;
    }
    fclose(f);
    return 0;
}

Rezultat

Nu pot deschide fișierul: No such file or directory

Greșeli frecvente

  • Nu verifici dacă fopen a returnat NULL. Orice funcție apelată apoi cu pointerul NULL oprește programul.
  • Deschizi cu "w" un fișier pe care voiai doar să-l completezi. "w" șterge tot conținutul fără să întrebe; pentru adăugare folosește "a".
  • Uiți fclose. Datele scrise pot rămâne în buffer și nu ajung pe disc dacă programul se oprește brusc.
  • Scrii o cale de Windows cu un singur backslash: "C:\date\note.txt". În C, \n din șir devine rând nou. Scrie "C:\\date\\note.txt" sau "C:/date/note.txt".

Comenzi înrudite

  • fprintf: Scrie text formatat într-un fișier sau în stderr, cu același șablon ca printf.
  • fscanf: Citește valori dintr-un fișier după un șablon, ca scanf; returnează câte câmpuri a citit sau EOF la final.
  • fread și fwrite: Scriu și citesc blocuri de octeți (tablouri, struct-uri) într-un fișier binar; fseek și ftell mută și arată poziția curentă.
  • fgets: Citește un rând întreg (cu tot cu spații) într-un tablou de caractere, fără să depășească dimensiunea dată.
  • errno, perror și strerror: errno păstrează codul ultimei erori a unei funcții de bibliotecă; perror și strerror îl transformă într-un mesaj citibil.