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 seule"w"
: écriture seule"r+"
ou "a"
: écriture seule (ajout)"a+"
: lecture et écriture (ajout)int fclose(FILE* f);
* Complète les opérations et
ferme le 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
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
)