Correction tp7
Correction tp7
Correction tp7
Programmation en C (LC4)
Pour toutes les opérations sur les fichiers, il faut inclure le header stdio.h (c’est à dire mettre un
#include<stdio.h> au début du programme).
Un fichier s’identifie par son nom. À partir du nom d’un fichier, on peut ouvrir un «canal» per-
mettant de lire ou écrire dans ce fichier. Le type de ces canaux est nommé FILE. Il s’agit d’un
type «abstrait», dont la définition dépend fortement du système. On ne doit donc pas chercher à
regarder à l’intérieur, mais simplement appeler dessus les fonctions standards décrites ci-dessous.
Ces fonctions travaillent en fait toutes avec des FILE *.
Pour ouvrir un canal vers un fichier, on utilise la fonction
FILE * fopen(char * nom_de_fichier, char * mode).
Le mode sert à spécifier quelle sorte de canal l’on veut. On utilisera le mode «écriture», dénommé
par la chaine "w" et le mode «lecture», dénommé par la chaine "r". Ainsi les lignes :
FILE ∗ f 1 ;
f 1 = f o p e n ( ”b l o p ” , ”r ” ) ;
ouvrent le fichier blop en lecture. Le fichier doit exister si on cherche à le lire, par contre, si on
l’ouvre en mode écriture et qu’il n’existe pas, il sera créé automatiquement. Si il existe déjà, il sera
tronqué. Si l’ouverture échoue, fopen renvoie NULL. Si elle réussie, fopen renvoie un pointeur vers
un canal, et l’on peut par la suite passer ce pointeur en argument aux diverses fonctions travaillant
sur des FILE *.
Pour fermer un canal après l’avoir utilisé, on utilise FILE * fclose(FILE * fichier). Il ne faut
pas faire de free, car fclose fait déjà ce qu’il faut. Il est indispensable de fermer un canal après
utilisation, pour au moins deux raisons :
– Les écritures dans un canal ne sont pas immédiates, elles sont regroupées en gros blocs, pour des
raisons d’efficacité, donc il reste souvent des données en attente d’écriture, et la fermeture du
canal déclenche l’écriture de ces données
– Il y a souvent des limites au nombre de canaux qu’un programme peut avoir ouvert simultané-
ment.
Si la fermeture réussie, fclose renvoie 0, autrement il renvoie la valeur EOF (une macro définie par
stdio.h, qui a de multiples usages).
On se retrouve avec le code suivant :
// d e b u t de l a m a n i p u l a t i o n du f i c h i e r
FILE ∗ f 1 ;
i f ( ( f 1 = f o p e n ( ”b l o p ” , ”r ”))==NULL) {
p r i n t f ( ”%s ” , ” e r r e u r l o r s de l ’ o u v e r t u r e de b l o p \n ” ) ;
exit (1);
}
// u t i l i s a t i o n du f i c h i e r . . .
// f i n de l a m a n i p u l a t i o n du f i c h i e r
i f ( f c l o s e ( f 1)==EOF) {
p r i n t f ( ”%s ” , ” e r r e u r l o r s de l a f e r m e t u r e de b l o p \n ” ) ;
exit (1);
}
La fonction pour lire un caractère depuis un canal fich est int fgetc(FILE * fich). Elle renvoie
un entier, qui est soit un caractère, soit la valeur EOF si on se trouve à la fin du fichier. Lorsqu’on
ouvre un fichier, le programme a un «curseur» situé au début du fichier. Les premiers caractères lus
seront les premiers caractères du fichiers. À chaque caractère lu, le curseur se décale d’un caractère
vers la fin du fichier.
Exercice 1 Créez avec votre éditeur un fichier exo1.txt où figurera uniquement votre prénom
puis votre nom séparés d’un espace.
Écrivez une fonction void prenom(FILE * f) qui lit le prenom sur le canal f censé pointer
vers exo1.txt, et l’affiche à l’écran. Lancez la deux fois de suite dans le main. Que se passe-t’il ?
I Exercice 2
void l i t p r e n o m ( FILE ∗ f ) {
int c ;
while ( ( ( c=f g e t c ( f ) ) ! = ’ ’ ) && ( c !=EOF) )
p r i n t f ( ”%c ” , c ) ;
}
Exercice 3 Écrivez une fonction compte_c(FILE * f) qui renvoie le nombre de caractères d’un
fichier.
Écrivez une fonction compte_m(FILE * F) qui renvoie le nombre de mots d’un fichier. Les
mots sont séparés par des espaces ou des retours à la ligne.
Écrivez une fonction compte_l qui renvoie le nombre de lignes.
I Exercice 4
int c o m p t e l ( FILE ∗ f ) {
int c ;
int c p t =0;
while ( ( c=f g e t c ( f ) ) ! =EOF)
i f ( c==’ \n ’ )
c p t++;
return c p t ;
}
Exercice 5 Faites un programme qui prend en argument sur la ligne de commande le nom d’un
fichier, et une lettre (c,m ou l) et qui renvoie selon cette lettre soit le nombre de caractères, de
mots ou de lignes du fichier.
I Exercice 6
Exercice 7 Écrivez un programme qui réécrit son code dans un autre fichier. Par exemple si
ce programme s’appelle exo_n.c, alors il crée un fichier copie_exo_n.c qui est une copie de
lui-même.
I Exercice 8
#include <s t d i o . h>
Plusieurs fonctions permettent de lire et écrire dans des fichiers. Il existe entre autres fread et
fwrite qui s’emploient comme suit :
fread : int fread(void * tableau, size_t taille, size_t n, FILE *f). Cette fonction tente
de lire, dans le fichier f, n blocs de taille octets, et les écrit à l’adresse tableau, qui doit
donc pointer vers un tableau suffisamment grand que l’on aura créé au préalable. Elle renvoie
le nombre de blocs lus, qui peut être plus petit que n, par exemple si l’on a atteint la fin du
fichier, et elle renvoie 0 en cas d’erreur.
fwrite : int fwrite(void *tableau, int taille, int n, FILE *f) agit de manière similaire :
elle écrit, dans le fichier f un nombre n de blocs de taille taille octets qu’elle lit dans le ta-
bleau pointé par tableau. Elle renvoie le nombre de blocs écrits en résultat. Si il est inférieur
à n, c’est qu’il y a eu une erreur.
Exercice 9 À l’aide de ces deux fonction écrire les fonctions mon_getc et mon_putc qui agissent
comme les fonctions vues précédemment.I Exercice 10
Exercice 11 Écrivez un programme qui crée un formulaire : il prend en argument sur la ligne
de commande un nom de fichier et des mots et crée un fichier avec un mot par ligne.
I Exercice
12
void a f f i c h e e c r a n ( char ∗ s ) {
while ( ∗ s != ’ \0 ’ ) {
fputc (∗ s , stdout ) ;
s++;
}
}
I Exercice 16
char ∗ q u e s t i o n s [ ] = {
”Nom” , ”Prenom ” , ”age ” , ” f i l i e r e ” , ”A d r e s s e ” , NULL
};