Fichiers en C

Manipulation de fichiers, flux, E/S

Flux et pointeurs FILE*

Manipulation des fichiers en C

Ouverture/fermeture

FILE *fopen(const char *pathname, const char *mode);
int fclose(FILE *stream);

Modes d'ouverture

Mode Description
"r" Lecture seule
"w" Ecriture seule (ecrase)
"a" Ajout en fin
"r+" Lecture/ecriture
"w+" Lecture/ecriture (ecrase)
"rb","wb" Mode binaire

Verification obligatoire

FILE *f = fopen("data.txt", "r");
if (f == NULL) { perror("Erreur"); return 1; }

I/O caractere et ligne

I/O caractere par caractere

int fgetc(FILE *stream);    // Lit un caractere, EOF si fin
int fputc(int c, FILE *stream);
int ungetc(int c, FILE *stream);  // Replace un caractere

Copie de fichier

void copy_char(const char *src, const char *dst) {
    FILE *in = fopen(src, "r"), *out = fopen(dst, "w");
    int c;
    while ((c = fgetc(in)) != EOF) fputc(c, out);
    fclose(in); fclose(out);
}

I/O ligne par ligne

char *fgets(char *s, int size, FILE *stream);
int fputs(const char *s, FILE *stream);

I/O formatee

int fprintf(FILE *stream, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);

I/O binaire

I/O binaire

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

Copie par blocs

void copy_block(const char *src, const char *dst) {
    FILE *in = fopen(src, "rb"), *out = fopen(dst, "wb");
    char buf[4096]; size_t n;
    while ((n = fread(buf, 1, sizeof(buf), in)) > 0)
        fwrite(buf, 1, n, out);
    fclose(in); fclose(out);
}

Positionnement dans un fichier

Positionnement

int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
void rewind(FILE *stream);
Constante Signification
SEEK_SET Depuis le debut
SEEK_CUR Depuis position courante
SEEK_END Depuis la fin

Acces direct vs sequentiel

  • Sequentiel : lecture lineaire
  • Direct : fseek permet de sauter a n'importe quelle position

Recherche dichotomique dans un fichier

int binary_search_file(FILE *f, int target, int lo, int hi) {
    while (lo <= hi) {
        int mid = (lo + hi) / 2, val;
        fseek(f, mid * sizeof(int), SEEK_SET);
        fread(&val, sizeof(int), 1, f);
        if (val == target) return mid;
        if (val < target) lo = mid + 1;
        else hi = mid - 1;
    }
    return -1;
}

Tri externe

Tri externe par fusion

Quand les donnees ne tiennent pas en memoire.

Principe

  1. Fragmentation : Lire par blocs, trier chaque bloc en memoire, ecrire fichiers temporaires
  2. Fusion : Fusionner les fichiers temporaires 2 a 2

Algorithme simplifie

void external_merge_sort(const char *input, const char *output, size_t M) {
    int *buf = malloc(M);
    // Phase 1: fragmentation et tri des blocs
    // Phase 2: fusions successives
    free(buf);
}

Complexite

  • Passes : O(log(n/M))
  • I/O : O(n log(n/M)) lectures/ecritures