Aller au contenu

[C] Fichiers : Organisation séquentielle logique


Jericho

Messages recommandés

Bonjour,

Encore et toujours pour la même application (gestion d'un club de karaté avec des règles imposées), je dois gerer mon fichier compétition (comprennant NumCompetition, NomCompetition et Date (dans une structure) de façon séquentielle logique, c'est à dire, une sorte de liste chainées mais sans utiliser la pile.

Je parle de la pile car je recherche partout sur Internet des tutoriaux et je ne trouve que des listes chainées adaptées à la pile (malloc, ...).

C'est pourquoi je vous demande votre aide. Ce que j'ai saisi c'est que j'aurais 3 pointeurs quand aux positions : un pointeur de début de liste, un pointeur de fichier suivant (inséré dans la structure competition pour chaque entrée) et un pointeur de fin (emplacement libre).

Je sais aussi que je dois enregistrer mes fichiers à la suite un par un (sans tri), le tri n'aura lieu que "théoriquement" grâce au pointeur_suivant et donc, lors de l'affichage de mes competitions, elles seront classées par ordre chronologique...

J'espère que je n'ai pas été trop confu et merci pour votre aide!

(voici ce que j'ai déjà (pas grand chose)) :

Déclaration en global :

struct date
{
int jour;
int mois;
int annee;
};

typedef struct competitions ptcompet;
struct competitions
{
int ptsuiv;
long NumCompetition;
struct date DateCompetition;
char NomKata[30];
};

[code]FILE *competfic;
ptcompet competficvar;
char nom_competfic[]="c:inpressgbdcompetitions.dat";

#define nbCompetitions 50

Fonction ajout des competitions (encore aucun enregistrement dans les fichiers) :

void ajout_competition (void)
{
char kata[4][15];
char buf[30];
char choix;
int bol,bol2,bol3;
long tmp;
int i;
int vdate,adate;
int tannee,tmois,tjour;

tannee=0;
tmois=0;
tjour=0;

strcpy(kata[0], "Mawashi");
strcpy(kata[1], "Tekki Shodan");
strcpy(kata[2], "Heidan Nidan");
strcpy(kata[3], "Heidan Shodan");

competfic=fopen(nom_competfic, "r+b");
choix=' ';
system("cls");
if(competfic)
{
	printf("Le fichier %s a bien ete ouvert.n",nom_competfic);
}
else
{
	printf("Le fichier %s n existe pas.", nom_competfic);
	printf("nAppuyer sur une touche pr le creer...");
	getch();
	fopen(nom_competfic,"ab");
	printf("nn...n");
	printf("nLe fichier %s a ete cree avec succes.", nom_competfic);
	getch();
}
fcloseall();	

   competfic=fopen(nom_competfic, "r+b");
   choix=' ';

bol=0;

do
{
	fflush(stdin);

	system("cls");
	printf("nAjout de Competitions");
	printf("n----------------");

	do
	{
		bol=-1;
		fseek(competfic,0,SEEK_SET);
		fflush(stdin);
		printf("nEntrer le numero de competition (ex : 001, 107) : ");
		scanf("%ld", &competficvar.NumCompetition);

		tmp=(long)competficvar.NumCompetition;

		fread(&competficvar, sizeof(ptcompet), 1, competfic);

		while(!feof(competfic))
		{
			if(tmp==competficvar.NumCompetition)
			{
				printf("nttNumero de license deja existant!n");
				bol=0;
			}
			fread( &competficvar, sizeof(ptcompet), 1, competfic);				
		}
	}
	while(bol==0);

	bol=-2;
	bol2=0;

	do
	{
		printf("nEntrer le nom de la competition : ");
		fflush(stdin);
		gets(buf);
		for(i=0;i<4;i++)
		{
			bol=stricmp(kata[i],buf);
			if(bol==0)
			{
				bol2=1;
				i=5;
				strcpy(competficvar.NomKata, buf);
			}
		}
		if(bol!=0)
		{
			printf("nnLe nom de la competition doit être :");
			printf("nMawashi ou Tekki Shodan ou Heidan Nidan ou Heidan Shodannn");
			bol2=0;
		}

	}
	while(bol2==0);

	bol3=0;

	vdate=1;
	adate=1;

	while(vdate==1 || adate==1)
	{
		fflush(stdin);
		printf("nEntrer sa date de naissance (jj/mm/aaaa) : ");
		scanf("%d/%d/%d", &competficvar.DateCompetition.jour, &competficvar.DateCompetition.mois, &competficvar.DateCompetition.annee);

		tannee=competficvar.DateCompetition.annee;
		tmois=competficvar.DateCompetition.mois;
		tjour=competficvar.DateCompetition.jour;

		vdate=verif_date(tannee,tmois,tjour);
		adate=verif_date_compet();

		if(vdate==1)
		{
			printf("nntt - Date incorrecte!n");
		}
		if(adate==1)
		{
			printf("nntt - La date doit être egale a aujourd'hui ou superieure!n");
		}
	}



}
while(choix=='o');			

fcloseall();
}

Lien à poster

j'ai pas regardé tout le code, mais j'ai relevé une erreur dans ta structure competitions

j'aurais fait un truc du genre

struct _compet

{

long NumCompetition;

struct date DateCompetition;

char NomKata[30];

struct _compet *suivant;

};

autre remarque, evite les system("cls"); je sais que c'est pour effacer l'ecran, mais bon.

En fait ce que tu veux faire, c'est un ajout directement au fichier ??

sequentiel logique ca veut rien dire.

ton fichier il ressemblera a quoi ? texte ? binaire ?

plutot du genre

1;competition lambda;02/02/06

2;competition beta;02/02/06

3;competition gamma;02/02/06

ou

1;competition lambda;02/02/06

3;competition gamma;02/02/06

2;competition beta;02/02/06

pour faire une liste chainée, et ordonnée il te faudra nécessairement utiliser des malloc. ou alors tu alloue un tableau de structure de la taille maximale

tu auras plusieurs fichier ou juste un fichier avec plusieur enregistrement ??

fait attention au vocabulaire que tu emplois lorsque tu décris ton probleme, parce que meme en relisant plusieur fois je comprends pas exacement ce que tu attends. J'ai l'idee generale, mais comme tu n'est pas tres précis, et clair, cela ouvre la porte a bon nombre de solutions, qui ne sont pas forcement toutes adaptée a ce que tu souhaite

Lien à poster

En fait, mes consignes sont "claires" : mon fichier compétition doit être organisé de manière "séquentielle logique"... Seulement, j'ai fait mes recherches la dessus et je n'ai rien trouvé.

En demandant des renseignements à ma prof, j'ai compris qu'en gros, elle voulait que j'ajoute des informations dans le fichier compétition à la suite l'une de l'autre (sans tri) mais que lors de l'encodage, ma "competition" (ainsi que sa date et son numero) recevrait un numéro (pointeur suivant). Ce pointeur, pointerait l'adresse de l'emplacement du prochain élément.

Ces valeurs seraient "triées" et attribuées après l'encondage en fonction d'un ordre chronologique.

Ex : si j'inscris B, puis A, puis C

Mon pointeur de début se mettrait à A, lirait le ptsuivant de A qui dirigerait vers B qui ensuite lirait le ptsuivant de B qui redirigerait vers C.

J'espère que j'ai été plus clair mais moi-même ne comprennant pas extrêmement bien la demande, j'ai du mal :D

Lien à poster

ok, voilà qui est clair, donc, ton fichier ressemblera à cela :

1;competition lambda;02/02/06

3;competition gamma;26/04/06

2;competition beta;15/06/06

la derniere compétition ajoutée dans le fichier n'est pas forcement la derniere dans l'ordre chronologique.

pour realiser cela, ouvre ton fichier en ecriture avec le drapeau "append"

fopen(filename, "a+");

le + sert a autoriser la lecture dans le fichier comme habituellement.

du coup, suffit de lire le fichier sequentiellement :

while(!feof(f))

{

fgets(str_line, 1024, f);

/* faire quelque chose avec la ligne */

}

a partir de la chaine str_line, tu cherche les token ";" par exemple pour les séparateur de champs, avec strtok http://www.cplusplus.com/ref/cstring/strtok.html , ou alors un simple sscanf("%s;%s;%s", &NumCompetition, NomKata, str_date);

ensuite tu stocke ta structure dans ta liste chainée (pas forcement doublement chaine, mais tout cela dependra de ton algorithme de tri. le plus simple etant quand meme la doublement chainée.

le principe serait :

1. verifier la date avec la précédente, si inférieur, alors recommencer, sinon verifier avec la suivante. Si supérieure a la suivante, alors insérer la competition, si inférieure a la suivante, alors recommencer.

cela dit, il vaut mieux commencer par verifier avec les suivante et remonter dans la liste, plutot que de commencer et descendre. enfin tu verras quand tu implementeras.

voilà pour les lignes principale.

Lien à poster

Bon, je me suis un peu lancé comme je le sentais et je pense que ca pourrait fonctionner mais ca ne fonctionne pas :D J'ai encore une fois besoin de vous :sorry

J'ai changé ma structure :

typedef struct competitions ptcompet;
struct competitions
{
int suiv;
int place;
long NumCompetition;
struct date DateCompetition;
long totaldate;
char NomKata[30];
};

FILE *competfic;
ptcompet competficvar;
char nom_competfic[]="c:inpressgbdcompetitions.dat";

#define nbCompetitions 50

Voici mon code :


void tri_chaine_competitions (void)
{
long tab[50];
int suivant[50];
int fin;
int i, j;
long temp;
int tmpsuiv;

fin=0;
j=0;

for(i=0;i<50;i++)
{
	tab[i]=0;
	suivant[i]=0;
}

competfic=fopen(nom_competfic, "r+b");

//Enregistrement des dates dans le tableau : 
fseek(competfic,0,SEEK_SET);
i=0;
while(!feof(competfic))
{
	tab[i]=competficvar.totaldate;
	i++;
	fread( &competficvar, sizeof(ptcompet), 1, competfic);
}
//Tri des dates : 
for(i=0;i	{
	for(j=0;jtab[j+1])
		{
			temp=tab[j+1];
			tab[j+1]=tab[j];
			tab[j]=temp;
		}
	}
}

tmpsuiv=-1;


//Attribution des pointeurs "Suivant"
fseek(competfic,0,SEEK_SET);

j=0;

for(i=tmpplace-1;i>=0;i--)
{
	fseek(competfic,0,SEEK_SET);
	while(j		{
		fread( &competficvar, sizeof(ptcompet), 1, competfic);
		if(tab[i]==competficvar.totaldate)
		{
			competficvar.suiv=tmpsuiv;
			tmpsuiv=competficvar.place;
			fwrite(&competficvar,sizeof(ptcompet), 1, competfic);
		}
                       j++;
	}
}


//Affichage des dates (test)
fseek(competfic,0,SEEK_SET);
while(i	{
	fread( &competficvar, sizeof(ptcompet), 1, competfic);
	printf("nPlace : %ld, Date : %ld, Suiv : %ld", competficvar.place, competficvar.totaldate, competficvar.suiv);	
	i++;
} // cet affichage est un test et me donne -1 pour chaque "suiv"
getch();

fcloseall();
}

tmpplace est défini en global avec le nombre d'enregistrement

Je pense que ca viendrait de ce bout la :

for(i=tmpplace-1;i>=0;i--)
{
	fseek(competfic,0,SEEK_SET);
	while(j		{
		fread( &competficvar, sizeof(ptcompet), 1, competfic);
		if(tab[i]==competficvar.totaldate)
		{
			competficvar.suiv=tmpsuiv;
			tmpsuiv=competficvar.place;
			fwrite(&competficvar,sizeof(ptcompet), 1, competfic);
		}
                       j++;
	}
}

Je ne comprends vraiment pas pourquoi mon suivant est toujours à -1 (je l'initialise à -1 mais il devrait s'écrire!)

Merci pour votre aide :sorry

Lien à poster

premier point: tu es sur des donnée que tu lis ? genre faire un affichage des champs de la structure lors de la lecture

deuxiement : dans le bout de code suivant :

while(!feof(competfic))

{

tab=competficvar.totaldate;

i++;

fread( &competficvar, sizeof(ptcompet), 1, competfic);

}

je te conseille de lire avant de traiter :), fait le fread en premier !

et

for(i=0;i<;tmpplace;i++)

{

for(j=0;j<;tmpplace-1;j++)

{

je te conseille de virer les ; inutiles :D i<;tmpplace

troisiement : regarde l'algorithme du tri a bulle, relativement simple et efficace.

while(j<;tmpplace)

{

idem : supprime le ; inutile

et enfin je ne vois nul par d'affectation de competficvar.suiv

Lien à poster

Les ; s'ajoutent quand je mets les balises [.code] sur le forum parce que dans mon code, ils n'y sont pas :D

Le tri que j'utilise est le tri bulle justement... C'est le seul que j'ai retrouvé de mes cours d'algo mais si je me rappelle bien c'est un "très bon".

J'affecte competficvar.suiv dans la fonction de saisie des competitions, pour chaque fiche je l'initialise à -1 et competifcvar.place prend le numéro de l'enregistrement (le cinquième aura 5).

void ajout_competition (void)
{
char kata[4][15];
char choix;
int bol;
int vdate,adate;
int tannee,tmois,tjour;
int choixnom;

tmpplace=0;

competfic=fopen(nom_competfic, "ab");

tannee=0;
tmois=0;
tjour=0;

strcpy(kata[0], "Mawashi");
strcpy(kata[1], "Tekki Shodan");
strcpy(kata[2], "Heidan Nidan");
strcpy(kata[3], "Heidan Shodan");

competfic=fopen(nom_competfic, "r+b");
choix=' ';
system("cls");
if(competfic)
{
	printf("Le fichier %s a bien ete ouvert.n",nom_competfic);
}
else
{
	printf("Le fichier %s n existe pas.", nom_competfic);
	printf("nAppuyer sur une touche pr le creer...");
	getch();
	fopen(nom_competfic,"ab");
	printf("nn...n");
	printf("nLe fichier %s a ete cree avec succes.", nom_competfic);
	getch();
}	

   choix=' ';

bol=0;

do
{
	tmpplace=0;
	competfic=fopen(nom_competfic, "r+b");
	fseek(competfic,0,SEEK_SET);
	while(!feof(competfic))
	{
		tmpplace++;
		fread( &competficvar, sizeof(ptcompet), 1, competfic);
	}
	fcloseall();

	competfic=fopen(nom_competfic, "ab");
	fseek(competfic,0,SEEK_SET);


	fflush(stdin);

	system("cls");
	printf("nAjout de Competitions");
	printf("n----------------");

	printf("nLe numero de cette competition est : %d.", tmpplace);
	competficvar.NumCompetition=tmpplace;

	bol=-2;

	choixnom=1;

	do
	{
		printf("nNom de competition : n");
		printf("nAppuyez sur 1 pour Mawashi");
		printf("nAppuyez sur 2 pour Tekki Shodan");
		printf("nAppuyez sur 3 pour Heidan Nidan");
		printf("nAppuyez sur 4 pour Heidan Shodan");
		printf("nnChoix : ");
		fflush(stdin);
		scanf("%d", &choixnom);

		switch(choixnom)
		{
		case 1 : strcpy(competficvar.NomKata,kata[0]);
			break;
		case 2 : strcpy(competficvar.NomKata,kata[1]);
			break;
		case 3 : strcpy(competficvar.NomKata,kata[2]);
			break;
		case 4 : strcpy(competficvar.NomKata,kata[3]);
			break;
		default : printf("ntErreur de choix!n");
				  choixnom=0;
			break;
		}
	}
	while(choixnom==0);


	competficvar.place=tmpplace;
	competficvar.suiv=-1;

	vdate=1;
	adate=1;

	while(vdate==1 || adate==1)
	{
		fflush(stdin);
		printf("nEntrez la date de la competition : (jj/mm/aaaa) : ");
		scanf("%d/%d/%d", &competficvar.DateCompetition.jour, &competficvar.DateCompetition.mois, &competficvar.DateCompetition.annee);

		tannee=competficvar.DateCompetition.annee;
		tmois=competficvar.DateCompetition.mois;
		tjour=competficvar.DateCompetition.jour;

		competficvar.totaldate=((tannee*10000)+(tmois*100)+tjour);

		vdate=verif_date(tannee,tmois,tjour);
		adate=verif_date_compet();

		if(vdate==1)
		{
			printf("nntt - Date incorrecte!n");
		}
		if(adate==1)
		{
			printf("nntt - La date doit être egale a aujourd'hui ou superieure!n");
		}
	}
	fwrite(&competficvar,sizeof(ptcompet), 1, competfic);

	printf("nnVoulez-vous ajouter un autre membre? ((O)ui - (N)on)n");
	fflush(stdin);
	scanf("%c", &choix);

	fcloseall();

}
while(choix=='o');

fcloseall();

tri_chaine_competitions();
}

(désolé pour la longueur)

Le problème c'est qu'il ne m'attribue pas les competficvar.suiv, il laisse -1 partout (j'ai essayé d'initialiser tmpsuiv à -2 pour voir si ca ne venait pas de la mais ce n'est pas ca...

Arg ca m'énerve, j'ai l'impression d'être prêt du "but" et je bloque (en fait, le prog fait actuellement +/- 2000 lignes)... Je vais devenir fou O.o

J'ai l'impression que ca vient de mon fwrite... J'ai essayé d'assigner d'abord les suiv dans un tableau de variable et ensuite de les passer à competficvar.suiv à l'aide d'une simple boucle mais ca ne fonctionne pas non plus...

Edit : Je viens de regarder dans le débuger et competficvar.suiv prend à chaque fois la bonne valeur dans la boucle, c'est donc le fwrite qui foire, il n'écrit pas :?

Lien à poster

Bon voilà, j'ai un peu remodifié ma boucle et mon "assignation" fonctionne bien, c'est donc le fwrite qui miche...

for(i=tmpplace-1;i>=0;i--)
{
	fseek(competfic,0,SEEK_SET);
	while(j		{
		fread( &competficvar, sizeof(ptcompet), 1, competfic);
		if(tab[i]==competficvar.totaldate)
		{
			competficvar.suiv=tmpsuiv;
			tmpsuiv=competficvar.place;
			fwrite(&competficvar,sizeof(ptcompet), 1, competfic);
			j=tmpplace;
		}
		else
		{
			j++;
		}
	}
	j=0;
}
fcloseall();

Mais je ne comprends pas du tout pourquoi :? :?

Lien à poster
×
×
  • Créer...