Les Fichiers 1 Les fichiers standards Ceux quon

  • Slides: 52
Download presentation
Les Fichiers 1

Les Fichiers 1

Les fichiers standards • Ceux qu’on a utilisés jusqu’à présent sont le clavier et

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: 2

Les entrée-sorties • Après avoir exploré les types de données et les opérateurs du

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. 3

 • Le langage C nous fournit des fonctions prédéfinies de lecture à partir

• 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> 4

La fonction getchar(); La fonction getchar permet la récupération d'un seul caractère à partir

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. 5

La fonction putchar(); La fonction putchar permet l'affichage d'un seul caractère sur l'écran de

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); } 6

La fonction scanf(); Les deux fonctions déjà évoquées bien qu'utiles présentent un inconvénient majeur:

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: 7

 • scanf(chaîne de contrôle, var 1, var 2, . . . , var.

• scanf(chaîne de contrôle, var 1, var 2, . . . , var. N); "où chaîne de contrôle" représente certaines données de formattage et "var 1, var 2, . . . , var. N" 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. 8

 • La syntaxe du groupe possède alors la forme générique suivante: • %[largeur]type

• 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: 9

Type de Données à récupérer c caractère d nombre entier e ou f un

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 10

1) i est un entier. Pour obtenir i de l'utilisateur on écrit: scanf("%d", &i);

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 11

 • 4) i et j sont deux entiers. i ne doit pas être

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

La fonction printf(); Comme la fonction scanf(); permet d'acquérir tout type de données à

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, arg 1, arg 2, . . . , arg. N); 13

 • où "chaîne de contrôle" représente certaines données de formattage et "arg 1,

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

Le groupe possède la forme générique suivante: %[flag][largeur]. [précision]type Les éléments entre crochets sont

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) 15

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

• Les différents types sont donnés dans le tableau suivant: • Type c d f s e Signification un caractère un entier un réel une chaîne de caractères notation exponentielle 16

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

• 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, ffff en format x et 377777 en format o. 17

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

Pour les réels, nous avons: • e, f, g – pour les réels à afficher en format décimal flottant avec (e)xposant [+-]ddd. nnnnnn. E[+-]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. 18

 • • • float x; double y; x = y = acos((double) -1);

• • • float x; double y; x = y = acos((double) -1); printf("Simples flottants %f %e %gn", x, x, x); printf("Flottants doubles %f %e %gn", y, y, y); printf("Simples flottants+ %18. 12 f %18. 12 e %18. 12 gn", x, x, x); • printf("Flottants doubles+ %18. 12 f %18. 12 e %18. 12 gn", y, y, y); 19

donne: • Simples flottants 3. 141593 e+00 3. 14159 • Flottants doubles 3. 141593

donne: • Simples flottants 3. 141593 e+00 3. 14159 • Flottants doubles 3. 141593 e+00 3. 14159 • Simples flottants+ 3. 141592741013 e+00 3. 14159274101 • Flottants doubles+ 3. 141592653590 e+00 3. 14159265359 20

Les différents "flags" sont donnés dans le tableau suivant: Flag + espace Signification justification

Les différents "flags" sont donnés dans le tableau suivant: Flag + espace Signification justification à gauche affichage du signe (+ ou -) avant la valeur numérique les valeurs positives sont précédées d’un espace valeur par défaut justification à droite uniquement le (-) est affichée aucun espace n’est affiché 21

Les fichiers non standards • En réalité, le clavier et l’écran sont des fichiers

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. 22

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

• 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; 23

 • Ceci a pour effet de créer logiquement un fichier. Cela n’est pas

• 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”); 24

 • Si la fonction fopen n’est pas capable d’effectuer l’opération demandée, le pointeur

• 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. 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. txtn”); 25

 • Une notion importante liée aux fichiers est celle de format. On doit

• 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. 26

 • Un fichier binaire est un fichier crée par un programme en exécution

• 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. 27

Exemple • • • • #include <stdio. h> int main () { int y=123;

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; } 28

 • Le format de fichier va encore plus loin cependant. Par exemple, les

• 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 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. 29

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

Prenons un exemple. • Supposons que l’on ait les deux fichiers suivants : • directe. txt • Patrice. Marc. Miles. Davis. Cliff. Burton. Donna • sequentiel. txt • Patrice. Marc. Miles. Davis. Cliff. Burton. Donna 30

 • On voit que puisque la taille des enregistrements de Directe. txt est

• 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. . 31

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

Principales fonctions de gestion de fichiers. • Ouverture/fermeture • FILE* fopen (const char* filename, const char* mode); • Ouvre le fichier « filename » selon le 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. 32

Lecture et écriture • int fread (void* buffer, size_t size, size_t count, FILE* stream);

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. • 33

 • int fscanf ( FILE * stream , const char * format [

• 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) ; 34

Position dans un fichier • long ftell ( FILE * stream ); • Retourne

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. 35

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

Un exemple • Écrire un programme qui copie un fichier dans un autre fichier. 36

 • • • #include <stdio. h> const int MAX = 20; int mai

• • • #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 lecturen”, in_name); printf(“ré-introduire le nom de fichier”); } 37

 • • /* avoir le nom du fichier dans lequel on veut écrire*/

• • /* 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 à %sn”, in_name, outp); return(0); } 38

Exemple 2 • Créer un fichier qui contient tous les nombres binaires entre 2

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

 • #include <stdio. h> FILE *binaryp • void main() • { • int

• #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); • } 40

 • Remarquer que dans ce cas, pour écrire dans le mode binaire nous

• 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 à écrire Le deuxième paramètre indique la longueur de chaque élément à écrire Le troisième paramètre indique le nombre de valeur à écrire Enfin le quatrième paramètre indique le ponteur de fichier sur lequel va porter cette écriture. 41

Exemple d’utilisation des fonctions de base sur les fichiers. • • • #include <stdlib.

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; }; 42

 • void Demander. Nom. Fichier (char Nom. Fichier[MAX]); • bool Fichier. Existe (char

• void Demander. Nom. Fichier (char Nom. Fichier[MAX]); • bool Fichier. Existe (char Nom[MAX]); • void Remplir (Eleve* Pat); • void Afficher (Eleve* Pat); • void Lire. Info (char Nom. Fichier[MAX], Eleve* E); • void Garder. Info (char Nom. Fichier[MAX], Eleve* E); • void Afficher. Fichier (char Nom. Fichier[MAX]); • void Afficher. Fichier. Ok (char Nom. Fichier[MAX]); • void Afficher. Enr (char Nom. Fichier[MAX], int No. Enr); 43

 • int main () • { • char Nom. Fichier[MAX]; • Demander. Nom.

• int main () • { • char Nom. Fichier[MAX]; • Demander. Nom. Fichier (Nom. Fichier); • • Eleve* Pat = (Eleve*) malloc(sizeof (Eleve)); • Remplir (Pat); • Afficher (Pat); • Garder. Info (Nom. Fichier, Pat); • Eleve *Bob = (Eleve*) malloc(sizeof (Eleve)); • 44

 • Lire. Info (Nom. Fichier, Bob); • Afficher (Bob); • printf ("nnn"); •

• Lire. Info (Nom. Fichier, Bob); • Afficher (Bob); • printf ("nnn"); • Afficher. Fichier (Nom. Fichier); • Afficher. Fichier. Ok (Nom. Fichier); • int No. Enr=0; • printf ("Numero d'entregistrement? "); • scanf ("%i", &No. Enr); • Afficher. Enr (Nom. Fichier, No. Enr); • return 0; • } 45

 • void Demander. Nom. Fichier (char Nom. Fichier[MAX]) • { • bool Existe=true;

• void Demander. Nom. Fichier (char Nom. Fichier[MAX]) • { • bool Existe=true; • do • { • printf ("Quel est le nom du fichier? "); • scanf ("%s", Nom. Fichier); • if (Existe = Fichier. Existe (Nom. Fichier)) • printf ("Existen"); • else • printf("Non, existe pasn"); • } • while (!Existe); • } 46

 • bool Fichier. Existe (char Nom[MAX]) • { • • • } bool

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

 • void Garder. Info (char Nom. Fichier[MAX], Eleve* E) • { • FILE*

• void Garder. Info (char Nom. Fichier[MAX], Eleve* E) • { • FILE* Fichier = fopen (Nom. Fichier, "ab"); • fwrite (E, sizeof (Eleve), 1, Fichier); • fclose (Fichier); • } 48

 • void Lire. Info (char Nom. Fichier[MAX], Eleve* E) • { • FILE*

• void Lire. Info (char Nom. Fichier[MAX], Eleve* E) • { • FILE* Fichier = fopen (Nom. Fichier, "rb"); • fread (E, sizeof (Eleve), 1, Fichier); • fclose (Fichier); • } • 49

 • • • • void Afficher. Fichier (char Nom. Fichier[MAX]) { printf ("Le

• • • • void Afficher. Fichier (char Nom. Fichier[MAX]) { printf ("Le contenu de %s est : n", Nom. Fichier); FILE* Fichier = fopen (Nom. Fichier, "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); } 50

 • • • • • void Afficher. Fichier. Ok (char Nom. Fichier[MAX]) {

• • • • • void Afficher. Fichier. Ok (char Nom. Fichier[MAX]) { printf ("nnn. Le contenu de %s est : n", Nom. Fichier); FILE* Fichier = fopen (Nom. Fichier, "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); } 51

 • void Afficher. Enr (char Nom. Fichier[MAX], int No. Enr) • { •

• void Afficher. Enr (char Nom. Fichier[MAX], int No. Enr) • { • FILE* Fichier = fopen (Nom. Fichier, "rb"); • fseek (Fichier, (No. Enr-1)*sizeof(Eleve), SEEK_SET); • Eleve E; • fread (&E, sizeof (Eleve), 1, Fichier); • fclose (Fichier); • Afficher (&E); • } 52