• Aucun résultat trouvé

Ce chapitre a introduit la notion de chier et présenté les principales fonctions permettant d'opérer sur les chiers en langage C selon leur type (texte ou binaire) et le mode d'accès sollicité (séquentiel ou direct). Plusieurs exemples relatifs à chaque fonction introduite ont été explicités avec détails. Les codes source ont été présentés avec capture d'écran des résultats de leur exécution. Ce chapitre sera complété par quelques énoncés d'exercices résolus et d'autres proposés comme test.

Les chiers Dr. Hada Bouziane USTO-MB 1 #include <stdio.h> 2 int main(){ 3 char nom_fich1[]="essai1.txt"; 4 char c; 5 int nbcar=0; 6 FILE *infile; 7 infile = fopen(nom_fich1,"r"); 8 if(infile == NULL) 9 {

10 printf("Impossible d'ouvrir le fichier %s en lecture!\n",nom_fich1);

11 return 1;

12 }

13 while(!feof(infile))

14 { c = fgetc(infile); 15 if(c != EOF && c!= '\n')

16 nbcar++;

17 }

18 fclose(infile);

19 printf("\n Nombre de caractères du fichier = %d\n",nbcar);

20 }

Contenu du chier essai1.txt :

Figure 2.30  Exemple de chier texte ouvert en lecture pour compter le nombre de ses caractères. Résultat de l'exécution :

Figure 2.31  Compter le nombre de caractères dans un chier texte. Exercice 4 Copie du contenu d'un chier essai1.dat dans un chier essai2.dat.

1 #include <stdio.h>

2 int main()

3 {char nom_fich1[]="essai1.dat"; 4 char nom_fich2[]="essai2.dat";

5 char c;

6 FILE *infile, *outfile; 7 infile = fopen(nom_fich1,"r"); 8 if(infile == NULL)

9 {

10 printf("Impossible d'ouvrir le fichier %s en lecture!\n",nom_fich1); 11 return 1;

12 }

13 outfile = fopen(nom_fich2,"w");

14 if(outfile == NULL)

16 printf("Impossible d'ouvrir le fichier %s en écriture!\n",nom_fich2); 17 return 2; 18 } 19 while(!feof(infile)) 20 { c = fgetc(infile); 21 fputc(c,outfile); 22 } 23 fclose(infile); 24 fclose(outfile); 25 }

Contenu du chier essai1.dat :

Figure 2.32  Visualisation du chier source essai1.dat. Contenu du chier résultat essai2.dat après l'exécution du code :

Figure 2.33  Visualisation du chier cible essai2.dat. Exercice 5 : Fichier structuré

Soit T un tableau d'au plus 100 étudiants. En considérant la structure Etudiant dénie par : Matricule : entier ;

Nom, Prenom : chaine [20] ; Moyenne : réel ;

a) Écrire le code en C permettant de recopier tous les étudiants admis appartenant à T dans un chier ADMIS de type Etudiant (un étudiant est admis si sa moyenne est supérieure ou égale à 10).

b) Écrire le code permettant d'acher l'étudiant ayant la meilleure moyenne.

c) En supposant le chier trié par ordre décroissant des moyennes (de la plus grande à la plus petite), donner le code achant le dernier et l'avant dernier étudiant dans la liste.

1 #include <stdio.h>

2 #define NB 6 // Nombre d'étudiants à saisir

3 //Déclaration de la structure

4 typedef struct{

5 int Matricule;

6 char Nom[20],Prenom[20];

7 float Moyenne;}Etudiant;

8 Etudiant T[10],e;// e est utilisée pour la saisie des info d'un étudiant

9 // Recopier les étudiants admis

10 /* Ici la solution est donnée en utilisant un fichier binaire, bien entendu il est possible d'utiliser

un fichier texte et lire/écrire dedans à

11 l'aide de fscanf() et fprintf() (lecture/écriture formatée) */

12 void recopier(){

13 FILE *outfile; 14 int i;

Les chiers Dr. Hada Bouziane USTO-MB 16 if(outfile==NULL)

17 printf("Impossible d'ouvrir le fichier en écriture \n");

18 else 19 { 20 for(i=0;i<NB;i++) 21 if(T[i].Moyenne >= 10) 22 { 23 printf("%s\t%s\n",T[i].Nom,T[i].Prenom); 24 fwrite(T+i,sizeof(Etudiant),1,outfile); 25 } 26 fclose(outfile); 27 }} 28 //*******************************************************

29 // Afficher le ou les étudiants ayant la meilleure moyenne

30 void bestMoy(float max) // max est calculée dans le main

31 {FILE *outfile;

32 outfile = fopen("ADMIS","rb"); 33 if(outfile==NULL)

34 printf("Impossible d'ouvrir le fichier en lecture \n");

35 else

36 {

37 printf("\nEtudiants dont la moyenne est %f :",max); 38 while(!feof(outfile))

39 {

40 fread(&e,sizeof(Etudiant),1,outfile); 41 if(e.Moyenne == max)

42 printf("\nMatricule : %d\tNom : %s\tPrenom : %s\n", e.Matricule,e.Nom,e.Prenom);

43 }

44 fclose(outfile);

45 }}

46 //*******************************************************

47 // Afficher le dernier et avant dernier étudiant

48 void derniers()

49 {FILE *outfile;

50 outfile = fopen("ADMIS","rb"); 51 if(outfile==NULL)

52 printf("Impossible d'ouvrir le fichier en lecture \n");

53 else

54 {

55 printf("\nDerniers etudiants figurant dans le fichier des admis:\n"); 56 fseek(outfile,0,SEEK_END);

57 fread(&e,sizeof(Etudiant),1,outfile);

58 printf("\nDernier -> Matricule : %d\tNom : %s\tPrenom : %s\n", e.Matricule,e.Nom,e.Prenom); 59 fseek(outfile,-2*sizeof(Etudiant),SEEK_CUR);

60 fread(&e,sizeof(Etudiant),1,outfile);

61 printf("\nAvant dernier -> Matricule : %d\tNom : %s\tPrenom : %s\n", e.Matricule,e.Nom,e.Prenom); 62 }}

63 int main(){

64 FILE *outfile; 65 float max=0; 66 int i;

67 //Boucle pour la saisie des infos du Tableau pour chaque étudiant 68 printf("Saisie des informations des etudiants \n");

69 for(i=0;i<NB;i++)

70 {

72 scanf("%d",&T[i].Matricule); 73 printf("Entrer le nom :"); 74 scanf("%s",T[i].Nom); 75 printf("Entrer le prenom :"); 76 scanf("%s",T[i].Prenom); 77 printf("Entrer la moyenne :"); 78 scanf("%f",&T[i].Moyenne); 79 }

80 // Recopier dans un fichier les etudiants admis

81 recopier();

82 //Afficher l'etudiant ayant la meilleure moyenne

83 /* Il est aussi possible de chercher le max directement dans le tableau au lieu du fichier*/

84 outfile = fopen("ADMIS","rb");

85 if(outfile==NULL)

86 {printf("Impossible d'ouvrir le fichier en lecture \n");

87 return 1; 88 } 89 while(!feof(outfile)) 90 { 91 fread(&e,sizeof(Etudiant),1,outfile); 92 if(e.Moyenne > max) 93 max = e.Moyenne ; 94 } 95 bestMoy(max);

96 //Afficher le dernier et avant dernier étudiants

97 derniers();

98 }

Résultat de l'exécution :

Les chiers Dr. Hada Bouziane USTO-MB

Exercice 6 Compléter ce code en ajoutant une fonction achant le nombre d'enseignantes et en prévoyant une mise à jour des informations saisies.

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define nb 10 5 typedef struct{ 6 int num; 7 float salaire; 8 char nom[20],prenom[40];

9 char sexe; // Le caractère 'F' pour féminin et 'M' pour masculin

10 char dept[20];

11 int fonction; // 0 pour employé et 1 pour enseignant

12 }Employe;

13 int main(){

14 int choix;

15 Employe e[nb],v[nb]; 16 FILE *infile, *outfile; 17 int i;

18 do

19 {

20 printf("\n\nMenu :\n");

21 printf("1 : Saisie des employes\n");

22 printf("2: Affichage de tous les employes\n"); 23 printf("3 : Quitter\n");

24 printf("Faites votre choix S.V.P : "); 25 scanf("%d",&choix); 26 switch(choix) 27 {case 1: 28 outfile = fopen("employe","wb"); 29 if(outfile !=NULL) 30 { 31 for(i=0;i<nb;i++)

32 {printf("\n Saisir l'employe N◦ %d \n",i+1); 33 printf("\nEntrer le numero : "); 34 scanf("%d",&e[i].num); 35 printf("\nEntrer le salaire : "); 36 scanf("%f",&e[i].salaire); 37 printf("\nEntrer le nom : "); 38 scanf("%s",e[i].nom); 39 printf("\nEntrer le prenom : "); 40 scanf("%s",e[i].prenom); 41 fflush(stdin); 42 printf("\nEntrer le sexe F/M: "); 43 scanf("%c",&e[i].sexe); 44 printf("\nEntrer le departement : "); 45 scanf("%s",e[i].dept); 46 printf("\nEntrer la fonction 0/1 : "); 47 scanf("%d",&e[i].fonction); 48 } 49 fwrite(e,sizeof(Employe),nb,outfile); 50 fclose(outfile); 51 } 52 break;

53 case 2 :

54 // Affichage de tous les employes saisis

55 infile = fopen("employe","rb"); 56 if(infile != NULL) 57 { 58 fread(v,sizeof(Employe),nb,infile); 59 for(i=0;i<nb;i++) 60 printf("\nEmploye N◦%d : %d %f %s %s %c %s %d",i+1,v[i].num,v[i].salaire,v[i].nom,v[i].prenom ,v[i].sexe,v[i].dept,v[i].fonction); 61 fclose(infile); 62 } 63 break; 64 case 3 :

65 // Autre traitement à compléter ou Fin

66 printf("\n Fin de traitement, Au revoir et Merci !\n");

67 break;

68 default :

69 printf(" Oups Vous avez fait un mauvais choix !\n");

70 }} while(choix!=3);

71 }

Exercice 7 : Traitement sur un chier structuré à faire

Etant donné une structure Voiture d'une agence de location de voitures. La structure est dénie par : • Le matricule qui est lui même une structure dénie par :

- char nb[7] ; - int annee ; - int Wilaya ;

• La marque (chaîne de 10 caractères) ; • L'état du véhicule (0 :disponible et 1 : loué) ; Ecrire la fonction principale (main) permettant de :

a) Créer un chier binaire permettant d'enregistrer les informations de 20 véhicules de l'agence. b) Acher le modèle et la marque de tous les véhicules disponibles (non loués) de l'année en cours. c) Acher le nombre de véhicules par wilaya.

Dr. Hada Bouziane USTO-MB

CHAPITRE

3

LES LISTE CHAÎNÉES

Sommaire

3.1 Introduction . . . 71 3.2 Les pointeurs. . . 71 3.3 Gestion dynamique de la mémoire. . . 73 3.4 Les listes chaînées. . . 76 3.5 Quelques opérations sur les listes chaînées . . . 78 3.6 Listes chaînées bidirectionnelles . . . 93 3.6.1 Création d'une liste bidirectionnelle. . . 94 3.6.2 Quelques opérations sur une liste bidirectionnelle . . . 94 3.7 Structures de données particulières . . . 97 3.7.1 Les piles . . . 97 3.7.2 Les les . . . 113 3.7.3 Résumé . . . 133

Figures

3.1 Pointeurs : adresse et contenu. . . 71 3.2 Pointeurs : accès au contenu des variables pointées. . . 71 3.3 Exemple de manipulation de pointeurs. . . 72 3.4 Pointeurs : pointeur sur un pointeur. . . 72 3.5 Exemple de pointeur sur un pointeur. . . 73 3.6 Structure d'une liste chaînée. . . 76 3.7 Liste chaînée simple. . . 76 3.8 Création d'une liste chaînée simple selon le principe LIFO (Last In,First Out), le dernier entré sera le

premier dans la liste. . . 80 3.9 Création d'une liste chaînée simple selon le principe FIFO (First In, First Out), premier entré sera

premier dans la liste. . . 84 3.10 Insertion en tête de liste.. . . 84 3.11 Insertion en queue de liste. . . 85 3.12 Insertion à une position l de la liste, l donnée.. . . 86 3.13 Insertion après l'élément d'adresse p, p donnée. . . 88 3.14 Suppression d'une valeur val, val donnée. . . 89 3.15 Liste circulaire simple. . . 93 3.16 Liste chaînée bidirectionnelle. . . 93 3.17 Liste bidirectionnelle circulaire. . . 96 3.18 Structure d'une pile. . . 97 3.20 Implémentation d'une pile par un tableau. . . 98 3.22 Implémentation d'une pile par une liste chaînée.. . . 100 3.23 Implémentation d'une pile par un tableau : mise en ÷uvre. . . 105 3.24 Implémentation d'une pile par une liste chaînée : mise en ÷uvre. . . 109 3.25 Exemple d'utilisation de la classe générique stack en C++. . . 111 3.26 Structure d'une le. . . 113 3.27 Implémentation d'une le par un tableau avec indice tete xe et indice queue variable. . . 114 3.28 Implémentation d'une le par un tableau avec indices tete et queue variables dite par ots. . . 116

3.30 Implémentation d'une le par un tableau circulaire.. . . 118 3.32 Implémentation d'une le par une liste chaînée. . . 120 3.33 Implémentation d'une le par un tableau circulaire : mise en ÷uvre. . . 126 3.34 Implémentation d'une le par une liste chaînée : mise en ÷uvre.. . . 130 3.35 Exemple d'utilisation de la classe générique queue en C++. . . 132

Les liste chaînées Dr. Hada Bouziane USTO-MB

3.1 Introduction

Rappelons tout d'abord ce que veut dire la notion de structure de données. Une structure de données est une manière d'organiser les données utilisées dans un algorithme pour l'implémenter sur machine. On distingue les structure de données séquentielles ou linéaires, les arbres et les graphes. Cette partie introduit les structures linéaires de base, l'appellation est due à la notion de séquence qui existe entre les éléments de la structure. Jusqu'ici, nous avons vu les tableaux dont les éléments de même type sont organisés de façon contiguë en mémoire et dont la réservation en mémoire nécessite à priori, le nombre maximum d'éléments (la taille maximale) qui désormais ne pourra pas changer mais il y'a aussi les listes, les piles et les les. Les trois derniers modèles sont considérés comme des types abstraits de données puisqu'ils peuvent concrètement être implémentés soit sous forme de tableaux (structures de données statiques), soit sous forme de listes chaînées (structures de données dynamiques) qui contrairement aux tableaux, elles n'ont pas de dimension gée à la création et leurs éléments sont dispersés en mémoire et reliés entre eux par des références ou pointeurs. Les éléments d'une structure de données dynamique sont crées au fur et à mesure (au besoin) par allocation dynamique de la mémoire et peuvent être détruites à tout moment comme nous allons voir avec plus de détails dans ce qui suit. Avant cela, il convient de rappeler la notion de pointeurs et son rapport avec l'allocation dynamique de la mémoire, principe de base des listes chaînées.

Documents relatifs