FILE*
: type “opaque” désignant un fichier ouvert1 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.
FILE* fopen(char* fichier, char* mode);
mode
: mode d’ouverture
"r"
: lecture"w"
: écriture. Curseur au début du fichier"a"
: ajout. Curseur à la fin du fichier"r+"
, "w+"
, "a+"
: lecture et
écritureint fclose(FILE* f);
* Complète les opérations et
ferme le fichier
Pour plus de détails concernant les modes d’ouverture,
man fopen
indique:
r
: Ouvre le fichier en lecture. Le pointeur de flux est
placé au début du fichier.r+
: Ouvre le fichier en lecture et écriture. Le
pointeur de flux est placé au début du fichier.w
: Ouvre le fichier en écriture. Le fichier est créé
s’il n’existait pas. S’il existait déjà, sa longueur est ramenée à 0. Le
pointeur de flux est placé au début du fichier.w+
: Ouvre le fichier en lecture et écriture. Le fichier
est créé s’il n’existait pas. S’il existait deja, sa longueur est
ramenée à 0. Le pointeur de flux est placé au début du fichier.a
: Ouvre le fichier en ajout (écriture à la fin du
fichier). Le fichier est créé s’il n’existait pas. Le pointeur de flux
est placé à la fin du fichier.a+
: Ouvre le fichier en lecture et ajout (écriture en
fin de fichier). Le fichier est créé s’il n’existait pas. Le pointeur de
flux est placé à la fin du fichier.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 !
int fprintf(FILE* f, char* format, ...);
printf
, mais écrit dans le fichier
f
size_t fwrite(void* ptr, size_t size, size_t nmemb, FILE* f);
size
\(\times\)nmemb
octets situés à
l’adresse ptr
dans f
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:
(f, "%d", 12); fprintf
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;
(&n, sizeof(int), 1, f); fwrite
Le fichier contiendra donc les octets 0x0C
0x00
0x00
0x00
, c’est à dire les
4 octets d’un int
dont la valeur est 12
.
Puisqu’un FILE*
désigne en fait un flux, on peut
utiliser fprintf
pour écrire sur la sortie standard
d’erreur :
(stderr, "Warning: flux capacitor overlow !\n"); fprintf
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) {
(stderr, "USAGE = %s fichier_source fichier_destination\n", argv[0]);
fprintfreturn EXIT_FAILURE;
}
/* open the input and output files */
FILE*f =fopen(argv[1], "r");
(f);
assertFILE*f_out =fopen(argv[2], "w");
(f_out);
assertchar line[1024];
int lineno = 1;
/* read the input file line by line */
while(fgets(line, 1024, f)) {
/* write the line to the output file */
(f_out, "%s", line);
fprintf++;
lineno}
/* close the files */
(f);
fclose(f_out);
fclosereturn 0;
}
int fscanf(FILE* f, char* format, ...);
scanf
, mais lit depuis le fichier
f
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* f);
nmemb
\(\times\)size
octets et les
stocke à l’adresse ptr
fread
renvoie une valeur < nmemb
si la
fin du fichier (EOF
) est atteintechar* fgets(char* s, int size, FILE* f);
size
caractères et les stocke dans
s
size
si lit n
ou
EOF
Ces 3 fonctions sont généralement utilisées chacune dans un cas précis:
fscanf
est utilisée pour lire des valeurs et les
stocker dans des variables. Par exemple:int a;
float b;
(f, "%d\t%f\n", &a, &b); fscanf
fread
est utilisée pour charger le contenu d’une (ou de
plusieurs) structure(s):struct s {
int a;
float b;
char c;
};
struct s tab[10];
(tab, sizeof(struct s), 10, f); fread
fgets
est utilisée pour lire un fichier ligne par
ligne:char line[1024];
int lineno = 1;
while(fgets(line, 1024, f)) {
("line %d: %s\n", lineno, line);
printf++;
lineno}
Position dans le fichier à laquelle la prochaine opération aura lieu
r
, r+
, w
,
w+
a
ou
a+
Avance à chaque opération de lecture/écriture
long ftell(FILE *stream);
int fseek(FILE *f, long offset, int whence);
offset
octets depuis
whence
vaut
SEEK_SET
)whence
vaut
SEEK_CUR
)whence
vaut
SEEK_END
)