Fichiers

François Trahay

Entrées-sorties bufferisées

1 Pour être exact, il s’agit de la bibliothèque standard (la libc)

Plus précisement, FILE* désigne un flux. Ce flux peut être un fichier, mais également des flux standards (stdin, stdout, ou stderr), des tubes, des sockets, etc.


Ouverture/fermeture

Après appel à la fonction fclose, f (le FILE*) devient inutilisable : le pointeur pointe vers une zone mémoire qui a peut être été libérée par fclose. Il convient donc de ne plus utiliser le fichier !


Primitives d’écriture

binaire vs. ascii

Quelle est la différence entre printf et fwrite ? La fonction fprintf écrit un ensemble de caractères ASCII dans le fichier, alors que fwrite écrit un ensemble de bits.

Ainsi, pour écrire la valeur 17 dans un fichier en ASCII, on peut exécuter:

fprintf(f, "%d", 12);

Le fichier contiendra donc les octets 0x31 (le caractère '1'), et 0x32 ('2').

Pour écrire la valeur 12 en binaire, on peut exécuter:

int n=12;
fwrite(&n, sizeof(int), 1, f);

Le fichier contiendra donc les octets 0x0C 0x00 0x00 0x00, c’est à dire les 4 octets d’un int dont la valeur est 12.

Sortie d’erreur

Puisqu’un FILE* désigne en fait un flux, on peut utiliser fprintf pour écrire sur la sortie standard d’erreur :

fprintf(stderr, "Warning: flux capacitor overlow !\n");

Exemple

Voici un programme montrant l’utilisation de primitives de lecture et d’écriture:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char**argv) {
  if (argc != 3) {
    fprintf(stderr, "USAGE = %s fichier_source fichier_destination\n", argv[0]);
    return EXIT_FAILURE;
  }

  /* open the input and output files */
  FILE*f =fopen(argv[1], "r");
  assert(f);
  FILE*f_out =fopen(argv[2], "w");
  assert(f_out);
  char line[1024];
  int lineno = 1;
  /* read the input file line by line */
  while(fgets(line, 1024, f)) {
    /* write the line to the output file */
    fprintf(f_out, "%s", line);
    lineno++;
  }

  /* close the files */
  fclose(f);
  fclose(f_out);
  return 0;
}

Primitives de lecture

Ces 3 fonctions sont généralement utilisées chacune dans un cas précis:

int a;
float b;
fscanf(f, "%d\t%f\n", &a, &b);
struct s {
  int a;
  float b;
  char c;
};
struct s tab[10];
fread(tab, sizeof(struct s), 10, f);
char line[1024];
int lineno = 1;
while(fgets(line, 1024, f)) {
  printf("line %d: %s\n", lineno, line);
  lineno++;
}

Curseur