Tri dichotomique

cs_juju987 Messages postés 2 Date d'inscription samedi 25 juin 2011 Statut Membre Dernière intervention 22 juillet 2012 - 21 juil. 2012 à 17:46
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 23 juil. 2012 à 10:54
il nous a ete demandé de faire le tri dichotmique en c sous unix sur un tableau de chaine de caractere et des dates en c avec au moins le pere partage et regraoupe tandis que 2 fils font les tri sur chaque moitiée du tableau
comment faire pour importer les donnees du fichier et les stocke dans le tableau sans avoir une errur de segmentation

3 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
21 juil. 2012 à 20:25
Bonjour

Je rappelle que l'on ne fait ici ni le travail, ni la réflexion à la place du demandeur. Je t'invite donc à poster ici un code complet et à expliquer ce qui te bloque très précisément.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
cs_juju987 Messages postés 2 Date d'inscription samedi 25 juin 2011 Statut Membre Dernière intervention 22 juillet 2012
22 juil. 2012 à 14:21
voici le code
[code=c]
#include
#include
#include

const char* FICHIER_INITIAL = "fichier.txt";
const char* FICHER_RESULTAT = "fresultat.csv";
const int DECROISSANT = 1;
const int CROISSANT = 2;

//const char* SEP = ";";

// définition de la liste chainée sur laquelle va s'effectuer le tri
typedef struct Elt* Liste;
typedef char Chaine[50];
typedef char TypeLigne[256];
typedef struct Elt
{
Chaine ch; // chaine valeur de la rubrique pour cette ligne
TypeLigne ligne; // ligne corespondante ds le fichier
Liste svt; // elt suivant de la liste
} Elt;

// titre des rubriques
TypeLigne entete;

/*==============================================================*/
void ajouteElt(Liste *l, Chaine ch, TypeLigne ligne)
{ // ajoute une chaine en tete de liste
Liste e;

e = (Liste) malloc(sizeof(Elt));

sprintf(e->ch, "%s", ch);
sprintf(e->ligne, "%s", ligne);

e->svt = *l;
*l = e;
}
/*==============================================================*/


/*==============================================================*/
char* inversionDate(char* mot)
{
int indice=0, taille=4,j=6,k=2;
char inter;
while(indice < 2){
inter=mot[indice];
mot[indice]=mot[indice+6];
mot[indice+6]=inter;
indice++;
}
while(j < 8)
{
inter=mot[j];
mot[j]=mot[j+2];
mot[j+2]=inter;
j++;
}
while(taille < 6)
{
inter=mot[taille];
mot[taille]=mot[taille+2];
mot[taille+2]=inter;
taille++;
}
while(k < 4)
{
inter=mot[k];
mot[k]=mot[k+2];
mot[k+2]=inter;
k++;
}
return mot;
}
/*==============================================================*/


/*==============================================================*/
char* obtenirDate(char* mot)
{
int indice=0, taille=4,j=6,k=2;
char inter;
while(indice < 2){
inter=mot[indice];
mot[indice]=mot[indice+8];
mot[indice+8]=inter;
indice++;
}
while(k < 4)
{
inter=mot[k];
mot[k]=mot[k+2];
mot[k+2]=inter;
k++;
}
while(taille < 6)
{
inter=mot[taille];
mot[taille]=mot[taille+2];
mot[taille+2]=inter;
taille++;
}
while(j < 8)
{
inter=mot[j];
mot[j]=mot[j+2];
mot[j+2]=inter;
j++;
}

return mot;
}
/*==============================================================*/


/*==============================================================*/
void afficheListe(Liste l)
{// affiche tous les elts de l
Liste l1 = l; int i = 1;
while (l1 != NULL)
{
printf("%d> %s\n",i, l1->ligne);
l1 = l1->svt;
i++;
}
}
/*==============================================================*/


/*==============================================================*/
void stockeListe(Liste l, FILE* fich)
{// enregistre tous les elts de l ds le fich
Liste l1 = l; int i = 1;

//fich = fopen(FICHER_RESULTAT, "w");
//fprintf(fich, "%s\n", entete);
while (l1 != NULL)
{
//printf("%d> %s\n",i, l1->ligne);
fprintf(fich, "%s\n", l1->ligne);
l1 = l1->svt;
i++;
}
//fclose(fich);
}
/*==============================================================*/


/*==============================================================*/
void suppEltDsListe(Liste *l, Liste lelt, Liste lpre)
{// supprime un elt de la liste avec son predecesseur donné
if(*l == lelt) // l'elt à supp est en tête
{
*l = (*l)->svt;
}
else
{
lpre->svt = lelt->svt;
}
free(lelt); // suppression de l'elt
}
/*==============================================================*/


/*==============================================================*/
void rechPlusPetit(Liste l, Liste* lmin, Liste* lpre)
{// renvoie l'@ du plus petit elt de la liste et celle de son predecesseur
Liste l1, l2;

l1 = l; l2 = NULL; *lmin = l; *lpre = NULL;
while(l1 != NULL)
{
if(strcmp((*lmin)->ch, l1->ch) > 0)
{
*lpre = l2;
*lmin = l1;
}
l2 = l1;
l1 = l1->svt;
}
}
/*==============================================================*/


/*==============================================================*/
void rechPlusGrd(Liste l, Liste* lmax, Liste* lpre)
{// renvoie l'@ du plus max elt de la liste et celle de son predecesseur
Liste l1, l2;

l1 = l; l2 = NULL; *lmax = l; *lpre = NULL;
while(l1 != NULL)
{
if(strcmp(l1->ch, (*lmax)->ch) > 0)
{
*lpre = l2;
*lmax = l1;
}
l2 = l1;
l1 = l1->svt;
}
}
/*==============================================================*/


/*==============================================================*/
void triDecListe(Liste l, Liste* ltriee)
{ // effectue le trie décroissant de la liste
Liste lmin, lpre, lres = NULL;
Chaine ch;
TypeLigne ligne;

while(l != NULL)
{
rechPlusPetit(l, &lmin, &lpre);

sprintf(ch, "%s", lmin->ch);
sprintf(ligne, "%s", lmin->ligne);

suppEltDsListe(&l, lmin, lpre);
ajouteElt(&lres, ch, ligne);
//l1 = l1->svt;
}
*ltriee = lres;
}
/*==============================================================*/


/*==============================================================*/
void triCroiListe(Liste l, Liste* ltriee)
{ // effectue le trie croissant de la liste
Liste lmax, lpre, lres = NULL;
Chaine ch;
TypeLigne ligne;

while(l != NULL)
{
rechPlusGrd(l, &lmax, &lpre);
sprintf(ch, "%s", lmax->ch);
sprintf(ligne, "%s", lmax->ligne);

suppEltDsListe(&l, lmax, lpre);
ajouteElt(&lres, ch, ligne);
}
*ltriee = lres;
}
/*==============================================================*/


/*==============================================================*/
void extraitChamp(TypeLigne ligne, Chaine ch, int pos)
{// extrait de la ligne le champ en position pos à partir du sépérateur sep
int n, j;
char *str, *token, *saveptr, *sep = ";";
TypeLigne lg;
char *tab,*ta;
char* dacteconver;

sprintf(lg, "%s", ligne);
n = pos;
//printf("extr1: %s\n",ligne);
for (j = 0, str = lg; j!=n ; j++, str = NULL)
{
token = strtok_r(str, sep, &saveptr); //printf("ici: %d\n", pos);
if (token == NULL)
break;
} //printf("token: %s\n ligne extr: %s\n", token, ligne);
sprintf(ch, "%s", token);

// printf("extr2: %s\n", ligne);
}
/*==============================================================*/


/*==============================================================*/
void litValsRubriq(FILE *fich, Liste* l, int posRubriq)
{// lit les valeurs d'une rubrique du fichier csv et les stocke sans redondance ds une liste
Chaine ch;
char* p;
TypeLigne ligne,lig;

//fich=fopen(FICHIER_INITIAL,"r");

while(fgets(ligne, sizeof ligne, fich))
{ /* supprime le \n(causé par fgets) à la fin de la ligne*/
p = strchr(ligne, '\n');
if(p != NULL)
*p = 0;

extraitChamp(ligne, ch, posRubriq);//printf("ici: %s\n", ch);

ajouteElt(l, ch, ligne);
}

//fclose(fich);
}
/*==============================================================*/


/*==============================================================*/
int nbligneFich(const char * nomfichier)
{// Nombre de ligne du fichier nomfichier
FILE* fich;
TypeLigne lg;
int i = 0;

fich = fopen(nomfichier, "r");
while(fgets(lg, sizeof lg, fich))
{
i++;
}

fclose(fich);
return i;
}
/*==============================================================*/


/*==============================================================*/
void diviseFichier(const char * nomFichier, char * nomFichier1, char * nomFichier2)
{// divise un fichier en deux fichiers contenant la moitié du premier
int i, tailleFich1 = nbligneFich(nomFichier)/2;

FILE* f, *f1, *f2;
TypeLigne lg;
char* p;


f = fopen(nomFichier, "r");
f1 = fopen(nomFichier1, "w");
f2 = fopen(nomFichier2, "w");

fgets(entete, sizeof entete, f); //printf("entete: %s\n", entete);
/* supprime le \n(causé par fgets) à la fin de la ligne*/
p = strchr(entete, '\n');
if(p != NULL)
*p = 0;

i = 0;
while(tailleFich1 > i)
{
fgets(lg, sizeof lg, f);
fputs(lg, f1);
i++;
}

while(fgets(lg, sizeof lg, f))
{
fputs(lg, f2);
}

fclose(f2);
fclose(f1);
fclose(f);
}
/*==============================================================*/


/*==============================================================*/
void trifichier(const char* nomFichierInit, const char* nomFichierFinal, int ordre, int posRubriq)
{/* trie le fichier nomFichierInit vers nomFichierFinal suivant l'ordre défini(décroissant ou croissant) par rapport à la rubrique indiquée*/

FILE* finit, *ffin;
Liste l1=NULL, l2=NULL;

finit = fopen(nomFichierInit, "r");
ffin = fopen(nomFichierFinal, "w");

litValsRubriq(finit, &l1, posRubriq);
if(ordre == CROISSANT) triCroiListe(l1, &l2);
else if(ordre == DECROISSANT) triDecListe(l1, &l2);
stockeListe(l2, ffin);

close(finit);
close(ffin);
}
/*==============================================================*/


/*==============================================================*/
void fusion(const char* nomF1, const char* nomF2, const char* nomFfin, int ordre, int posRubriq)
{// fait la fusion triée de deux fichiers déjà triés
FILE *f1, *f2, *f;
TypeLigne lg1, lg2;
Chaine ch1, ch2;
//int i = 0, taille = nbligneFich(nomF1) + nbligneFich(nomF2);
int fini = 0;

f1 = fopen(nomF1, "r");
f2 = fopen(nomF2, "r");
f = fopen(nomFfin, "w");

// met le fichier d'entete
fprintf(f, "%s\n", entete);

if(!fgets(lg1, sizeof lg1, f1))
{
fini=1; printf("lg1: %s\n", lg1);
}
else if(!fgets(lg2, sizeof lg2, f2))
{
fini=2; fini=1; printf("lg1: %s\n", lg2);
}

while(fini == 0)
{

extraitChamp(lg1, ch1, posRubriq);
extraitChamp(lg2, ch2, posRubriq);//printf("lg2: %s\n", lg2);
if(ordre == CROISSANT)
{
if(strcmp(ch1, ch2) < 0)
{
fputs(lg1, f);
if(!fgets(lg1, sizeof lg1, f1))
{
fini=1;
}
}
else
{
fputs(lg2, f);
if(!fgets(lg2, sizeof lg2, f2))
{
fini=2;
}
}
}
else if(ordre == DECROISSANT)
{
if(strcmp(ch2, ch1) < 0)
{
fputs(lg1, f);
if(!fgets(lg1, sizeof lg1, f1))
{
fini=1;
}
}
else
{
fputs(lg2, f);
if(!fgets(lg2, sizeof lg2, f2))
{
fini=2;
}
}
}
}

printf("fini = %d\n", fini);
if(fini == 1)
{
fputs(lg2, f);
while(fgets(lg2, sizeof lg2, f2))
fputs(lg2, f);
}
else if(fini == 2)
{
fputs(lg1, f);
while(fgets(lg1, sizeof lg1, f1))
fputs(lg1, f);
}

fclose(f1);
fclose(f2);
fclose(f);
}
/*==============================================================*/


/*=================================== PROGRAMME PRINCIPAL ===============================*/
int main()
{
Liste l = NULL;

//int posRubriq = 2;
int p1, p2;
char * f1init = "ftmp1.txt";
char * f2init = "ftmp2.txt";
char * f1fin = "ftmpf1.txt";
char * f2fin = "ftmpf2.txt";
int val;
//int ordre = CROISSANT;
int ordre ;
int posRubriq ;

// getchar();
//printf("Taille: %d\n", nbligneFich(FICHIER_INITIAL));
printf(" ************************************************************************* \n ");
printf(" ** ** \n ");
printf(" ** ** \n ");
printf(" ** TRAVAUX PRATIQUES DE SYSTEMES D'EXPLOITATION ** \n ");
printf(" ** ** \n ");
printf(" ** ** \n ");
printf(" ** Deuxième Année Ingénieur IAI ** \n ");
printf(" ** ** \n ");
printf(" ** ** \n");
printf(" ************************************************************************* \n ");
printf(" \n");
printf(" ** M E N U ** \n ");
printf(" \n");
printf(" Le tri sur les rubrique s'effectue de la manière suivante:\n");
printf(" \n");
printf(" 1- Pour effectuer le tri selon le matricule des agents, entrer [1]\n");
printf(" 2- Pour effectuer le tri selon le nom des agents, entrer [2]\n");
printf(" 3- Pour effectuer le tri selon le prenom des agents, entrer [3]\n");
printf(" 4- Pour effectuer le tri selon le sexe des agents, entrer [4]\n");
printf(" 5- Pour effectuer le tri selon la date de naissance des agents, entrer [5]\n");
printf(" 6- Pour effectuer le tri selon la date d'embauche des agents, entrer [6]\n");
printf(" 7- Pour effectuer le tri selon la date d'avancement des agents, entrer [7]\n");
printf(" 8- Pour effectuer le tri selon la catégorire des agents, entrer [8]\n");
printf(" 9- Pour effectuer le tri selon l'indice des agents, entrer [9]\n");
printf(" 10- Pour effectuer le tri selon la catégorie des agents, entrer [10]\n");
printf(" 11- Pour effectuer le tri selon la classe des agents, entrer [11]\n");
printf(" 12- Pour effectuer le tri selon les codes de directions des agents, entrer [12]\n");
printf(" 13- Pour effectuer le tri selon les codes de fonctions des agents, entrer [13]\n");
printf(" 14- Pour effectuer le tri selon les codes villes des agents, entrer [14]\n");
printf(" 15- Pour effectuer le tri selon les noms des villes des agents, entrer [15]\n");
printf("\n");

// diviseFichier(FICHIER_INITIAL, f1init, f2init);
rep:
printf("Entrer le numero de la rubrique à trier SVP: ");
scanf("\n %d",&posRubriq);
if(posRubriq15){
printf("Cette valeur ne correspond à aucune rubrique \n");
goto rep;

}

printf("Si vous voulez effectuer un tri par odre croissant, tapez [1]\n");
printf("Si vous voulez effectuer un tri par odre decroissant, tapez [2]\n");
printf("\n");
debut:
printf(" Entrez votre numéro: ");
scanf(" \n%d",&val);

if(val == 2 ){

ordre=DECROISSANT;
}
else if(val == 1 ){
ordre=CROISSANT;
printf("ici\n");
}
else{
printf("Numéro incorrecte");
goto debut;

}
diviseFichier(FICHIER_INITIAL, f1init, f2init);

p1 = fork(); // création du premier processus
if(p1)
{// exécution du père
p2 = fork();
if(!p2)
{// exécution du fils p2
trifichier(f2init, f2fin, ordre, posRubriq);
exit(2);
}
}
else
{// exécution du fils p1
trifichier(f1init, f1fin, ordre, posRubriq);
exit(1);
}

printf("FUSION\n"); getchar();
fusion(f1fin, f2fin, FICHER_RESULTAT, ordre, posRubriq);
// printf("%d\n",posRubriq);
//printf("%d\n",CROISSANT);
printf(" Le tri s'est terminé avec succès. \n");
}
/code
en effet ce code marche quand je desactive interface console et indice diretement dans mon programme l element du fiichier a trier .mais lorsque je le fais avec l interface console il m affiche un message d erreur de segmentation et me revoi de fichier vide
merci d avance
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
23 juil. 2012 à 10:54
Étant donné que tu ne m'as pas fourni le ou les fichiers textes qui allaient avec, difficile de tester...

Néanmoins, il semble que tu ne gères pas du tout les erreurs. Lorsque un fichier n'est pas trouvé, fopen renvoit une valeur nulle, et ça tu ne le testes jamais. Il y a 3 endroits ou tu ne le fais pas.

f = fopen(nomFfin, "w");
if (!f)
{
  /* Gestion erreur ?*/
}


De plus, as-tu lancé un gdb sur ton programme en mode debug, pour voir ce qui n'allait pas ? (J'ai trouvé 3 erreurs en lançant juste celui-ci sur ton programme).

Enfin, tu sembles utiliser un compilateur C++ pour faire du C (en C classique il n'y a pas de // mais juste /**/, on ne cast pas le retour du malloc, etc...).

Tu as aussi énormément de variables inutilisées, ou de fonctions non déclarées:
toto.c: In function &#8216;extraitChamp&#8217;:
toto.c:264:5: warning: implicit declaration of function &#8216;strtok_r&#8217; [-Wimplicit-function-declaration]
toto.c:264:11: warning: assignment makes pointer from integer without a cast [enabled by default]
toto.c:257:9: warning: unused variable &#8216;dacteconver&#8217; [-Wunused-variable]
toto.c:256:14: warning: unused variable &#8216;ta&#8217; [-Wunused-variable]
toto.c:256:9: warning: unused variable &#8216;tab&#8217; [-Wunused-variable]
toto.c: In function &#8216;litValsRubriq&#8217;:
toto.c:280:19: warning: unused variable &#8216;lig&#8217; [-Wunused-variable]
toto.c: In function &#8216;trifichier&#8217;:
toto.c:380:3: warning: implicit declaration of function &#8216;close&#8217; [-Wimplicit-function-declaration]
toto.c: In function &#8216;main&#8217;:
toto.c:562:3: warning: implicit declaration of function &#8216;fork&#8217; [-Wimplicit-function-declaration]
toto.c:483:10: warning: unused variable &#8216;l&#8217; [-Wunused-variable]

As-tu bien compilé avec tous les warnings activés ?

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
Rejoignez-nous