// cour_08/02/2003 : gestion de fichiers / liste chainée / tri


/*

1) lire un fichier et afficher son contenu

2) charger le contenu d'un fichier dans une liste chainée

3) trier alphabétiquement ou /et numériquement la liste chainée

4) sauvegarder la liste chainée triée dans un fichier

5) lire un fichier et afficher son contenu


  Analyse syntaxique d'un texte : un mot-clef(dit pivot) encadré des 3 /4 mots avant et 3 /4 mots après
	permet de donner un 'sens' au contexte

   */
#include <stdio.h>
#include <stdafx.h>
#include <string.h>

 // DECLARATIONS GLOBALES
	struct cel		 // cel : nom du type de cellule
	{ char nomVille[20];	
	  int nbHab;
	  int info;
	  cel * voisin;	 //reference recursive, pointeur vers le voisin = NULL si par de voisin
	  cel * precedent;	 //reference recursive, pointeur vers le voisin = NULL si par de voisin
	};
	struct cel  *tliste, *fliste;  // tete et fin de liste vers structure de type cel
	struct cel  *surf, *surf_avant;			 // pointeur pour parcourir la liste


	FILE  *pf;

	bool rep;

	int i;
	int i_mini=0,i_maxi=0;

	 // declaration des fonctions

 
/* 
	ouverture d'un fichier 
	 **********************
**/
bool ouvrir_fichier (char * mode)
{	char nom_fichier[20];

	 
/* demander le nom du fichier à ouvrir  */
	printf("\n Donnez le nom du fichier à ouvrir :");
	scanf("%s",&nom_fichier);
	printf("\n fichier à ouvrir -> %s",nom_fichier);

	 
/* tenter d'ouvrir le fichier et afficher un message d'erreur si erreur à l'ouverture  */
	pf=fopen(nom_fichier,mode);
	if (pf==NULL) {printf("\n *** erreur ouverture %s",nom_fichier); return false;}
	else {printf("\n ok, fichier %s ouvert",nom_fichier); return true;};

};

 
/*
	fermer du fichier
	 ********************
**/
void fermer_fichier()
{
	fclose(pf);
};



 
/*
	lecture du fichier
	 *****************
**/
void lire_fichier()
{	
	char ville[20];
	int hab;
	
	 // 1ere lecture
	fscanf(pf,"%s",&ville);
	fscanf(pf,"%i",&hab);

	while (!feof(pf))
	{
	 
/* afficher son contenu sur l'ecran  */
		printf("\n Ville:%s   Hab:%i",ville,hab);
	 
/* lire selon un certain mode, une structure d'enregistrement  */
		fscanf(pf,"%s",&ville);
		fscanf(pf,"%i",&hab);
	};

};


 
/*
	charger le fichier dans une liste
	 **********************************
**/
void ajouter_en_entete(char ville[20], int hab) {
	printf("\nAjouter un nouvel element en tete de liste");

	surf=new cel;  // creation d'une nouvelle structure cel et stockage de son adresse dans surf
 	strcpy((surf->nomVille),ville); 
 	(surf->nbHab)=hab; 


	surf->voisin=NULL;
	surf->precedent=NULL;

	if (fliste==NULL) {fliste=surf;} else {tliste->precedent=surf;};  // dans la cas d'une liste vide
	surf->voisin=tliste;  // surf pointe vers la premier element de la liste
	tliste = surf;  // le debut de liste pointe vers surf



};

void charger_fichier_dans_liste()
{
	char ville[20];
	int hab;

	int nbAjout=0;


	rep=ouvrir_fichier("r");  // ouvrir_fichier retourne TRUE si çà s'est bien passé
								 // FALSE sinon

	if (rep)  // rep = TRUE, c'est à dire si çà s'est bien passé : on traite
	{
	 
/* 1ere lecture  */
	fscanf(pf,"%s",&ville);
	fscanf(pf,"%i",&hab);

	while (!feof(pf))
		{
		 
/* charger son contenu dans la liste  */
			ajouter_en_entete(ville,hab);
			nbAjout++;

		 
/* autres lecture  */
			fscanf(pf,"%s %i",&ville,&hab);
		};  // fin while

	fermer_fichier();
	};  // fin if

	printf("%i",nbAjout);



};



 
/*
	trier la liste par nom
	 ***********************
**/
void trier_liste()
{
	 
/* pour un tableau
	var max:cle;
	var indice_max:entier;
	pour i de n à 2 par -1
		max=cle(i);indice_max=i;
		pour j de i-1 à 1 par -1
			si cle(j)>max alors
				max=cle(j)
				indice_max=j
			permuter tab(i) /tab(indice_max)
		 / tableau trie de i à n
	 */

	char max_cle[20];
	struct cel  *pmax;
	
	char sv_nomVille[20];
	int sv_nbHab;

	int indice_max=0;  //-> pointeur vers cellule maxi

	surf=fliste;

	while (!(surf==tliste)) 
	{
		strcpy(max_cle,surf->nomVille);
		printf("\n max_cle %s",max_cle);

		surf_avant=surf;

		pmax=surf_avant;
		while (!(surf_avant==NULL)) 
		{
			if (strcmp(surf_avant->nomVille,max_cle)>0)
			{ //si supérieur
				strcpy(max_cle,surf_avant->nomVille);
				printf("\n new max_cle %s",max_cle);
				pmax=surf_avant;
			};
			surf_avant=surf_avant->precedent;
		};

		 
/* permutter */
			 // sauvegarde surf

			printf("\n permutte %s : %s %s",max_cle,pmax->nomVille,surf->nomVille);

			strcpy(sv_nomVille,surf->nomVille);
			sv_nbHab=surf->nbHab;

			 // copie de max dans surf
			strcpy(surf->nomVille,pmax->nomVille);
			surf->nbHab=pmax->nbHab;

			 // copie de sv dans max
			strcpy(pmax->nomVille,sv_nomVille);
			pmax->nbHab=sv_nbHab;


			surf=surf->precedent;
	};

	
};


 
/*
	sauvegarder la liste dans un fichier
	 ***********************************
**/
void sauvegarder_liste()
{	
	if (tliste==NULL) 
		{printf("\n-- la liste est vide --");}
		else
		{
		 
/* ouvrir  */
		rep=ouvrir_fichier("w");
		if (rep)
		{
		surf=tliste;
		while (surf != NULL)
		{
			fprintf(pf,"%s %i\n",surf->nomVille,surf->nbHab);
			surf=surf->voisin;
		};  // fin while
	
		};  // fin if (rep)

		};  // fin if


};


void Ajouter_en_fin() {
	printf("\nAjouter un nouvel element en fin de liste");

	 // NOUVELLE VALEUR
	printf("\nSaisir une nouvelle donnée :");

	surf=new cel;  // creation d'une nouvelle structure cel et stockage de son adresse dans surf
 	scanf("%i",&surf->info);  // mettre la valeur saisie dans la zone info de la cellule
	getchar();

	surf->voisin=NULL;

	if (tliste==NULL) 
		{tliste=surf;}  // dans la cas d'une liste vide
		else
		{
		fliste->voisin = surf;  // le dernier element a pour voisin surf
		};  // la fin de liste pointe vers surf

	fliste=surf;


};

void Rechercher_un_element() {

	int rech=0;

	i=1;

	printf("\nRechercher un element dans la liste");

	printf("\nSaisir une valeur à chercher :");
 	scanf("%i",&rech); 
	getchar();

	surf=tliste;

	while (surf!=NULL)
		{
		if (surf->info==rech) {printf("\n -> trouvé à l'index %i",i);};
		i++;
		surf=surf->voisin;
		};  // fin while



};



void Afficher_les_elements() {
	printf("\nAfficher les elements de la liste");
	i_mini=0;
	i_maxi=0;
	if (tliste==NULL) {printf("\n-- la liste est vide --");}
	else
	{
	surf=tliste;
	i=1;
	i_mini=i;
	while (surf != NULL)
	{
		printf("\n %ieme element de la file %i",i,surf->info);
		surf=surf->voisin;
		i_maxi=i;
		i++;
	};  // fin while
	
	};

};


void Supprimer_un_element() {

	int rech = 0;

	printf("\nSupprimer un element de la liste");

	Afficher_les_elements();
	if (i_mini!=0)
	{

	printf("\nDonnez l'index de l'element à supprimer :");
	printf("\nentre %i et %i :",i_mini, i_maxi);
 	scanf("%i",&rech);
	getchar();
	if ((rech<i_mini)||(rech>i_maxi))
		{printf("\n *** index hors limites  ***");}
	else
		{printf("\nsuppression en cours");


	i=1;
	surf=tliste;
	surf_avant=NULL;

	while (i<rech)
	{printf("\n %ieme element de %i de la file %i",i,rech,surf->info);
	surf_avant=surf;
	surf=surf->voisin;
	i++;
	};

	printf("\n A SUPPRIMER :");	
	printf("\n %ieme element de %i de la file %i",i,rech,surf->info);

	 // surf est l'element à supprimer
	
	 // si 1er element : cad surf=tliste 
	 // tliste = surf->voisin
	if (rech==i_mini) { tliste=surf->voisin;} 
	
	 // si dernier element : cad surf=fliste
	 // fliste = avant_surf
	 // avant_surf->voisin==NULL
	else
	{
	if (rech==i_maxi)  { fliste=surf_avant; surf_avant->voisin=NULL; }

	 // autre :
	 // avant_surf->voisin==surf
	else
	{ surf_avant->voisin=surf->voisin;};

	};  // fin else

	 // ici : desallocation de la cellule pointée par surf

	};  // fin else

	};  // fin if (i_mini!=0)
};



void main()
{	
	printf("\nDebut de programme");

    rep=ouvrir_fichier("r");
	if (rep) {lire_fichier();	fermer_fichier();};


	charger_fichier_dans_liste(); 

	trier_liste();
   
	sauvegarder_liste();

	printf("\nFin de programme\n");
	
}