Les Fichiers

52
1 Les Fichiers

description

Les Fichiers. Les fichiers standards. Ceux qu’on a utilisés jusqu’à présent sont le clavier et l’écran: ce sont des fichiers standards. Les instructions du langage C appropriées pour les utiliser sont comme suit:. Les entrée-sorties. - PowerPoint PPT Presentation

Transcript of Les Fichiers

Page 1: Les Fichiers

1

Les Fichiers

Page 2: Les Fichiers

2

Les fichiers standards

• Ceux qu’on a utilisés jusqu’à présent sont le clavier et l’écran: ce sont des fichiers standards.

Les instructions du langage C appropriées pour les utiliser sont comme suit:

Page 3: Les Fichiers

3

Les entrée-sorties

• Après avoir exploré les types de données et les opérateurs du langage C nous passons maintenant à l'étude de quelques fonctions qui vont nous permettre de lire à partir du clavier et d'afficher sur l'écran de notre ordinateur. Après tout, tout programme aura besoin de données que nous devons lui fournir pour les manipuler et affichera en retour différents résultats sur l'écran.

Page 4: Les Fichiers

4

• Le langage C nous fournit des fonctions prédéfinies de lecture à partir du clavier et d'écriture sur l'écran qui sont contenues dans le "header file" stdio.h donc au début de tout programme qui devra utiliser ces fonctions nous devrons inclure au début la directive suivante: #include <stdio.h>

Page 5: Les Fichiers

5

La fonction getchar(); La fonction getchar permet la récupération d'un

seul caractère à partir du clavier. La syntaxe d'utilisation de getchar est la suivante:

variable=getchar();• notez que variable doit être de type char et les

parenthèses aprés getchar.

Page 6: Les Fichiers

6

La fonction putchar();

La fonction putchar permet l'affichage d'un seul caractère sur l'écran de l'ordinateur. La fonction putchar constitue alors la fonction complémentaire de getchar. La syntaxe d'utilisation est la suivante:

• putchar(variable);• où variable est de type char. • Exemple:

#include main(){char c;c=getchar();putchar(c);}

Page 7: Les Fichiers

7

 La fonction scanf();

Les deux fonctions déjà évoquées bien qu'utiles présentent un inconvénient majeur: que faire pour pouvoir entrer une chaîne complète ou même un nombre? Dans le cas d'un chaîne on devra construire une boucle et dans le cas d'un nombre on devra aussi convertir les caractères en chiffres, tout celà se montre très lourd. c'est alors que vient à l'aide la fonction scanf. En effet elle permet de récupérer n'importe quelle combinaison de valeurs numériques, de caractères et de chaînes. La syntaxe d'utilisation de scanf est la suivante:

Page 8: Les Fichiers

8

• scanf(chaîne de contrôle, var1, var2, ..., varN);

"où chaîne de contrôle" représente certaines données de formattage et "var1,  var2,..., varN" représentent les variables à remplir. La chaîne de contrôle est entourée de guillemets constituée de groupes de caractères chaque groupe étant en relation avec une des variables mentionnées. Le groupe devra commencer par le signe % suivi d'un nombre indiquant la largeur de la variable à lire et ensuite un caractère bien défini (le type) indiquant si la variable est un caractère, un nombre (soit entier soit décimal) ou une chaîne.

Page 9: Les Fichiers

9

• La syntaxe du groupe possède alors la forme générique suivante:

• %[largeur]type

• Notez que l'argument entre crochets est facultatif. Les différents types sont donnés dans le tableau suivant.

• Si la chaîne contient plus qu'un groupe il sont souvent séparés par des espaces et ainsi les données entrées doivent être séparées par des espaces. Le type de chaque variable doit correspondre au type de son groupe et chaque variable doit être précédée du signe & sauf si elle est une chaîne.

• Théorie difficile? passons aux exemples:

Page 10: Les Fichiers

10

Type de Données à récupérer

c caractère

d nombre entier

e ou f un nombre décimal en notation réelle (f) ou exponentielle (e)

s une chaîne de caractères

Page 11: Les Fichiers

11

1) i est un entier. Pour obtenir i de l'utilisateur on écrit:scanf("%d",&i);sur le clavier nous tapons: -->> 123

2) a est un caractère:scanf("%c",&a);-->> d

3) ville est une chaîne:scanf("%s",ville);                     ^                      |------------ pas de & car ville est une chaîne.

-->> beyrouth

Page 12: Les Fichiers

12

• 4) i et j sont deux entiers. i ne doit pas être plus large que trois chiffres:scanf("%3d %d",&i,&j);-->> 231 1024             ^              |---------- notez l'espace separateur

 

Page 13: Les Fichiers

13

La fonction printf();

Comme la fonction scanf(); permet d'acquérir tout type de données à partir du clavier, la fonction printf(); permet quant à elle d'afficher tout type de données à l'écran de l'ordinateur. Cette fonction permet d'afficher n'importe quelle combinaison de caractères de nombres et de chaînes.

La syntaxe de la fonction printf(); est la suivante:

• printf("chaîne" de contrôle,arg1, arg2,..., argN);

Page 14: Les Fichiers

14

• où "chaîne de contrôle" représente certaines données de formattage et "arg1, arg2,..., argN" les variables (ou éventuellement les expressions) à afficher. chaque groupe est en relation avec l'argument correspondant dans la liste des arguments.

Page 15: Les Fichiers

15

Le groupe possède la forme générique suivante:

%[flag][largeur].[précision]type

Les éléments entre crochets sont facultatifs. La largeur indique le nombre minimum de caractères affichés et la précision indique le nombre maximum de caractères affichés (pour un nombre décimal la précision indique le nombre maximal de caractères après la virgule qui est par défaut 6)

Page 16: Les Fichiers

16

• Les différents types sont donnés dans le tableau suivant:

• Type Signification

c un caractère d un entier f un réel s une chaîne de caractères e notation exponentielle

Page 17: Les Fichiers

17

• Pour les entiers, nous avons en réalité• d, u, o, x

– pour les entiers à afficher en (d)écimal , – sans signe -- (u)nsigned, – en (o)ctal sans signe, – ou en he(x)adécimal sans signe. Ainsi -1 (la

valeur maximum 11...1 sur 32 bits) donnera -1 en format d, 4294967295 (232) en format u, ffffffff en format x et 37777777777 en format o.

Page 18: Les Fichiers

18

Pour les réels, nous avons:• e, f, g

– pour les réels à afficher en format décimal flottant avec (e)xposant[+-]ddd.nnnnnnE[+-]xx,

– ou en format décimal format (f)ixe [-]ddd.nnnnnn. – La longueur des n est donnée par la précision sinon

elle est 6 par défaut. – Le format g est pour l' affichage le plus précis dans le

minimum d'espace.

Page 19: Les Fichiers

19

• float x; • double y; • x = y = acos((double) -1); • printf("Simples flottants %f %e %g\n", x, x, x); • printf("Flottants doubles %f %e %g\n", y, y, y); • printf("Simples flottants+ %18.12f %18.12e

%18.12g\n", x, x, x); • printf("Flottants doubles+ %18.12f %18.12e

%18.12g\n", y, y, y);

Page 20: Les Fichiers

20

donne:• Simples flottants 3.141593 3.141593e+00 3.14159

• Flottants doubles 3.141593 3.141593e+00 3.14159

• Simples flottants+ 3.141592741013 3.141592741013e+00

3.14159274101 • Flottants doubles+ 3.141592653590 3.141592653590e+00

3.14159265359

Page 21: Les Fichiers

21

Les différents "flags" sont donnés dans le tableau suivant:

Flag Signification valeur par défaut

- justification à gauche justification à droite

+ affichage du signe (+ ou -) uniquement le (-) est

avant la valeur numérique affichée

espace les valeurs positives sont aucun espace n’est

précédées d’un espace affiché

Page 22: Les Fichiers

22

Les fichiers non standards

• En réalité, le clavier et l’écran sont des fichiers qui ont le nom stdin et stdout, respectivement.

• En C, nous avons la possibilité de définir nos propres fichiers ans lesquels nous pouvons lire et écrire nos informations.

Ces fichiers, à l’opposé du clavier et de l’écran, puevent être sauvegardés et consultés ultérieurement.

Page 23: Les Fichiers

23

• Pour utiliser un fichier, il est necessaire de le déclarer avant tout.

• Pour ce faire, on utliise le mot reservé FILE *non du fichier

Exemple: FILE *infile; FILE *outfile;

Page 24: Les Fichiers

24

• Ceci a pour effet de créer logiquement un fichier. Cela n’est pas suffisant. Il faut encore lui donner une existence physique. Pour ce faire, on utilise:

• infile = fopen(fichier.txt, “r”);

• outfile = fopen(sortie.txt, “w”);

Page 25: Les Fichiers

25

• Si la fonction fopen n’est pas capable d’effectuer l’opération demandée, le pointeur de fichier qu’elle retourne est égal à la valeur associée avec l’identificateur NULL

• Si par exemple le fichier fichier.txt n’existe pas alors l’exécution de l’instruction suivante va afficher le message approprié suivant:

• if (infile == NULL) printf(“ne peut pas ouvrir en lecture le fichier

fichier.txt\n”);

Page 26: Les Fichiers

26

• Une notion importante liée aux fichiers est celle de format. On doit écrire l’information de façon à pouvoir la retrouver facilement. Il existe deux formats spécifiques en C : binaire et texte.

Les fichiers en format texte regroupent en octets l’information et permettent d’écrire des tabulations qui seront reconnues de même que des sauts de lignes.

Un entier écrit dans un fichier texte prendra en octets le nombre de chiffres de cet entier.

Les fichiers binaires écrivent l’information comme une suite de bits. Un entier écrit dans ce format prendra toujours quatre octets d’espace.

Page 27: Les Fichiers

27

• Un fichier binaire est un fichier crée par un programme en exécution en sauvegardant directement dans ce fichier dans la représnattion binaire chaque élément de ce fichier.

Page 28: Les Fichiers

28

Exemple

• #include <stdio.h>• int main ()• {• int y=123;• FILE* Fichier = fopen ("File.txt", "w");• fwrite (&y, sizeof (int), 1, Fichier);• fclose (Fichier);• Fichier = fopen ("File.bin", "wb");• fprintf (Fichier, "%i", y);• fclose (Fichier);•• return 0;• }

Page 29: Les Fichiers

29

• Le format de fichier va encore plus loin cependant. Par exemple, les données peuvent être encryptées ou encore être mises en lignes ou en colonnes, etc.

Type d’accès à un fichier• Il existe deux types d’accès au fichier : direct et

séquentiel. Un accès direct implique que l’on peut accéder aux parties

d’informations importantes d’un fichier sans avoir à lire les autres.

Dans un accès séquentiel, il faut lire toutes les données précédentes pour arriver à ce qui nous intéresse.

Page 30: Les Fichiers

30

Prenons un exemple.• Supposons que l’on ait les deux fichiers

suivants :• directe.txt• PatriceMarcMilesDavisCliffBurtonDonna

• sequentiel.txt• PatriceMarcMilesDavisCliffBurtonDonna

Page 31: Les Fichiers

31

• On voit que puisque la taille des enregistrements de Directe.txt est de 20 caractères il est possible de calculer où commence un enregistrement. Dans le cas de sequentiel.txt, c’est impossible, il faut lire le fichier pour savoir où sont les espaces.

• Il est possible d’effectuer un accès directe sur un fichier avec un fichier binaire et avec un fichier texte. Cependant, la plupart du temps, lorsque l’on veut effectuer un accès directe sur un fichier on utilise les fichiers binaires. .

Page 32: Les Fichiers

32

Principales fonctions de gestion de fichiers.• Ouverture/fermeture• FILE* fopen (const char* filename, const char*

mode); • Ouvre le fichier « filename »  selon le mode

mode indiqué. Retourne un pointeur sur le fichier. Le pointeur NULL est retourné si l’opération d’ouverture échoue.

• "r" : en lecture seulement mode texte.• "w" en écriture seulement et mode texte.• "wb" : en écriture seulement mode binaire.• "rb" : en lecture seulement mode binaire.

Page 33: Les Fichiers

33

Lecture et écriture

• int fread (void* buffer, size_t size, size_t count, FILE* stream);

• Lit un bloc de données d’un flux. Précisément, lit count blocs de taille size du flux stream et enregistre cette information dans buffer. Notons que la lecture est sans format. Retourne le nombre de blocs lus. Si la valeur retournée est différentes de count, une erreur est survenue ou la fin du fichier.

Page 34: Les Fichiers

34

• int fscanf ( FILE * stream , const char * format [ , argument , ...] ); • Lit des données formatées du flux stream. La syntaxe est la

même que celle de scanf. Exemple :• scanf (Fichier, "%s", Nom) ;• scanf (Fichier, "%i", &x) ;• size_t fwrite ( const void * buffer, size_t size, size_t count, FILE *

stream ); • Écrit un bloc de données dans un flux. Le bloc sera

composé de count blocs de taille size. Le flux est stream et l’information est lue dans buffer.

• int fprintf (FILE * stream , const char * format [ , argument , ...] ); • Écrit un bloc de données formatées. Même format que

printf. Exemple :• printf ("Salut %s, tu as %i ! ! ", Nom, Age) ;• printf ("%i", Taille) ;

Page 35: Les Fichiers

35

Position dans un fichier

• long ftell ( FILE * stream ); • Retourne la position du pointeur stream. Lorsque le fichier

est en mode binaire, le nombre retourné est le nombre d’octets du début à la position courante. En mode texte, à cause des retours de chariots, cette fonction est moins utilisée. Retourne le pointeur stream si tout s’est bien déroulé. Sinon, la valeur –1 est retournée.

• int fseek ( FILE * stream , long offset , int origin ); • Repositionne le pointeur stream. La nouvelle position est

un déplacement de taille offset par rapport à origin.• Les valeurs possibles pour origin sont :• SEEK_SET (0) : Début du fichier• SEEK_CUR (1) : Position courante• SEEK_END (2) : Fin du fichier.

Page 36: Les Fichiers

36

Un exemple

• Écrire un programme qui copie un fichier dans un autre fichier.

Page 37: Les Fichiers

37

• #include <stdio.h>• const int MAX = 20;• int mai ()• char in_name[MAX] ;• char out_name[MAX];• FILE *inp, *outp;• char car;• printf(“introduire le nom du fichier à copier”);• for (scanf(“%s”, in_name); (inp =fopen(in_name,”r”))==NULL;

scanf(“s%”, in_name))• { printf(“ne peut pas ouvrir %s pour lecture\n”,in_name); printf(“ré-introduire le nom de fichier”); }

Page 38: Les Fichiers

38

• /* avoir le nom du fichier dans lequel on veut écrire*/• printf(“introduire le nom du nouveau fichier”);

• outp =fopen(out_name, “w”)

for (car = getc(inp); car != eof; car =getc(inp)) putc(car, outp);

fclose(inp);fclose(outp);

printf(“copié %s à %s\n”, in_name, outp);return(0);}

Page 39: Les Fichiers

39

Exemple 2

• Créer un fichier qui contient tous les nombres binaires entre 2 et 500.

Page 40: Les Fichiers

40

• #include <stdio.h>

FILE *binaryp• void main()• {• int i;• binaryp = fopen(“nums.bin”, “wb”);• for (i=2; i <= 500; i+=2)• fwrite(&i, sizeof(int), 1, binaryp);• fclose(binaryp);• }

Page 41: Les Fichiers

41

• Remarquer que dans ce cas, pour écrire dans le mode binaire nous avons besoin de l’instrcution fwrite:

• fwrite(&i, size(int), 1, binaryp)Le premier paramètre indique l’adresse de la variable à

écrireLe deuxième paramètre indique la longueur de chaque

élément à écrireLe troisième paramètre indique le nombre de valeur à

écrireEnfin le quatrième paramètre indique le ponteur de fichier

sur lequel va porter cette écriture.

Page 42: Les Fichiers

42

Exemple d’utilisation des fonctions de base sur les fichiers.

• #include <stdlib.h>• #include <stdio.h>• const int MAX = 20;• struct Eleve• {• char Nom[MAX];• char Prenom[MAX];• int Age;• };

Page 43: Les Fichiers

43

• void DemanderNomFichier (char NomFichier[MAX]);

• bool FichierExiste (char Nom[MAX]);• void Remplir (Eleve* Pat);• void Afficher (Eleve* Pat);• void LireInfo (char NomFichier[MAX], Eleve* E);• void GarderInfo (char NomFichier[MAX], Eleve* E);• void AfficherFichier (char NomFichier[MAX]);• void AfficherFichierOk (char NomFichier[MAX]);• void AfficherEnr (char NomFichier[MAX], int

NoEnr);

Page 44: Les Fichiers

44

• int main ()• {• char NomFichier[MAX];• DemanderNomFichier (NomFichier);•• Eleve* Pat = (Eleve*) malloc(sizeof (Eleve));• Remplir (Pat);• Afficher (Pat);• GarderInfo (NomFichier, Pat);• Eleve *Bob = (Eleve*) malloc(sizeof (Eleve));•

Page 45: Les Fichiers

45

• LireInfo (NomFichier, Bob);• Afficher (Bob);• printf ("\n\n\n");• AfficherFichier (NomFichier);• AfficherFichierOk (NomFichier);• int NoEnr=0;• printf ("Numero d'entregistrement?");• scanf ("%i", &NoEnr);• AfficherEnr (NomFichier, NoEnr);• return 0;• }

Page 46: Les Fichiers

46

• void DemanderNomFichier (char NomFichier[MAX])• {• bool Existe=true;• do• {• printf ("Quel est le nom du fichier?");• scanf ("%s", NomFichier);• if (Existe = FichierExiste (NomFichier))• printf ("Existe\n");• else• printf("Non, existe pas\n");• }• while (!Existe);• }

Page 47: Les Fichiers

47

• bool FichierExiste (char Nom[MAX])• {• bool Retour = true;• FILE* Fichier = fopen (Nom, "rb");• if (Fichier != NULL)• {• fclose (Fichier);• Retour = true;• }• else• Retour = false;• return Retour;• }

Page 48: Les Fichiers

48

• void GarderInfo (char NomFichier[MAX], Eleve* E)

• {• FILE* Fichier = fopen (NomFichier, "ab");• fwrite (E, sizeof (Eleve), 1, Fichier);• fclose (Fichier);• }

Page 49: Les Fichiers

49

• void LireInfo (char NomFichier[MAX], Eleve* E)• {• FILE* Fichier = fopen (NomFichier, "rb");• fread (E, sizeof (Eleve), 1, Fichier);• fclose (Fichier);• }•

Page 50: Les Fichiers

50

• void AfficherFichier (char NomFichier[MAX])• {• printf ("Le contenu de %s est : \n", NomFichier);• FILE* Fichier = fopen (NomFichier, "rb");• int No=0;• while (!feof (Fichier))• {• No++;• Eleve E;• fread (&E, sizeof (Eleve), 1, Fichier);• printf ("Numero %i : \n",No);• Afficher (&E);• }• fclose (Fichier);• }

Page 51: Les Fichiers

51

• void AfficherFichierOk (char NomFichier[MAX])• {• printf ("\n\n\nLe contenu de %s est : \n", NomFichier);• FILE* Fichier = fopen (NomFichier, "rb");• fseek (Fichier, 0, SEEK_END);• int Nombre = ftell(Fichier)/sizeof (Eleve);• fseek (Fichier,0, SEEK_SET);• int No=0;• for (int y=0; y <Nombre; y++)• {• No++;• Eleve E;• fread (&E, sizeof (Eleve), 1, Fichier);• printf ("Numero %i : \n",No);• Afficher (&E);• }• fclose (Fichier);• }

Page 52: Les Fichiers

52

• void AfficherEnr (char NomFichier[MAX], int NoEnr)• {• FILE* Fichier = fopen (NomFichier, "rb");• fseek (Fichier, (NoEnr-1)*sizeof(Eleve),

SEEK_SET);• Eleve E;• fread (&E, sizeof (Eleve), 1, Fichier);• fclose (Fichier);• Afficher (&E);• }