Trier un fichier.txt, avec des pointeurs par QuickSort

Signaler
Messages postés
6
Date d'inscription
jeudi 25 novembre 2004
Statut
Membre
Dernière intervention
20 septembre 2005
-
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
-
Bonjour, je suis débuttante en C++ et j'ai besoin d'aide pour une fonction de tri.

Voila mon pb :
j'ai un fichier .txt tout simple avec des numéro de client, une quantité et un prix unitaire.
Et il faudrait que je fasse une fonction qui permette de trier mon fichier, et demander par la meme occasion, à l'utilisateur, son critère de tri (par numcli, par qté ou par PU). Cette fonction je dois la réaliser avec QuickSort.

Pouvez vous m'aider, s'il vous plait.
Merci
Aurélie

10 réponses

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
jette un oeil ici, quasi le meme exercice:
http://www.cppfrance.com/forum.v2.aspx?ID=279539

ciao...
BruNews, MVP VC++
Messages postés
6
Date d'inscription
jeudi 25 novembre 2004
Statut
Membre
Dernière intervention
20 septembre 2005

Ba j'ai regardé à l'adresse indiqué mais moi ce n'est pas vraiment le meme problème puisque je n'est pas de tableau, je travaille avec des pointeurs (c'est une liste chainée que j'ai). Et je n'arrive ni a trier ni a enregistrer les modifications !! Pouvez vous m'aidez s'il vous plait ??

Voici l'intégralité de mon code :

// debut1.cpp : Définition de la structure élément de la liste chainée
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct element{
char numcli[8];
int quantite;
float prix;
struct element *precedent;
struct element *suivant;
} elm;

typedef elm *pointeur_elm;

// prototype de toutes les fonctions éléments:
pointeur_elm charger(void);

// premier est le pointeur qui pointra toujours sur le premier élément de la liste chainée:
void afficher(pointeur_elm pt);
pointeur_elm supprimer(pointeur_elm pt);
pointeur_elm modifier(pointeur_elm pt);
pointeur_elm trier(pointeur_elm pt);
// pointeur_elm generer(pointeur_elm pt);
// void enregistrer(pointeur_elm pt);
void quitter(void);

void main(void)
{
int numero;

pointeur_elm premier;

do{
printf("\t MENU \t \n");
printf(" \n");
printf("1. Charger le fichier\n");
printf("2. Afficher le fichier\n");
printf("3. Supprimer un element du fichier\n");
printf("4. Modifier une ligne du fichier\n");
printf("5. Trier les elements du fichier sur le numero client\n");
printf("6. Generer les fichiers compta et erreur\n");
printf("7. Enregistrer le fichier\n");
printf("8. Quitter\n");
printf(" \n");
printf("Choisissez votre menu :\n");
fflush(stdin);
scanf("%d",&numero);

switch(numero){
case 1 :premier=charger();
break;
case 2 :afficher(premier);
break;
case 3 :premier=supprimer(premier);
break;
case 4 :premier=modifier(premier);
break;
case 5 :premier=trier(premier);
break;
//case 6 :premier=generer(premier);
//break;
//case 7 :premier=enregistrer(premier);
//break;
case 8 :quitter();
break;
default :printf("Ce n'est pas un menu\n\n");
}

}while(numero != 8);

}

// DESCRIPTION DES FONCTIONS :

// Fonction CHARGER :
pointeur_elm charger(void)
{
char fichier[40], pause;
// 3 nouveaux pointeurs elm (p, nouveau et courant):
pointeur_elm p = NULL, nouveau, courant;
// création d'un pointeur sur fichier:
FILE *fich;

printf("Saisir le chemin complet du fichier\n");
scanf("%s",fichier);

// fich va recevoir le pointeur en lecture sauf s'il n'existe pas:
if ((fich = fopen(fichier, "r"))==NULL)
{
printf("\nLe fichier n'existe pas\n");
// pour vider le buffer(tampon de la machine):
fflush (stdin);
// permet à l'utilisateur de taper une touche pour continuer (pause):
pause = getchar();
}

else
{
// chargement du fichier:
printf("\nDebut du chargement du fichier en memoire ... \n");

// allocation mémoire pour le pointeur "nouveau", convertit en pointeur sur élément:
nouveau = (pointeur_elm) malloc (sizeof(elm));
// lire les éléments d'un fichier: (déposer une chaine de caractère jusqu'à ce qu'il trouve un ;)
fscanf(fich,"%[^;]s", &(nouveau ->numcli));
// pour lire le ";" :
fscanf(fich,"%c",&pause);
// lire les autres éléments d'un fichier:
fscanf(fich,"%d",&(nouveau ->quantite));
fscanf(fich,"%c",&pause);
fscanf(fich,"%f",&(nouveau ->prix));
fscanf(fich,"%c",&pause);

nouveau ->suivant=NULL;
nouveau ->precedent=NULL;
p=nouveau;
courant=nouveau;

// Tant qu'on est pas à la fin du fichier:
while (!feof(fich))
{
nouveau = (pointeur_elm) malloc (sizeof(elm));
fscanf(fich,"%[^;]s", &(nouveau ->numcli));
fscanf(fich,"%c",&pause);
fscanf(fich,"%d",&(nouveau ->quantite));
fscanf(fich,"%c",&pause);
fscanf(fich,"%f",&(nouveau ->prix));
fscanf(fich,"%c",&pause);
courant ->suivant = nouveau;
nouveau ->precedent = courant;
nouveau ->suivant = NULL;
courant = nouveau;
printf("* ");
}
printf("*\nChargement termine\n");
fflush(stdin);
pause = getchar();

}
return p;
}

// Fonction AFFICHER :
void afficher(pointeur_elm pt)
{
pointeur_elm copie;
copie=pt;

// Affiche tous les éléments du fichier chargé :
while (copie != NULL)
{
printf("%s \t",copie->numcli);
printf("%d \t",copie->quantite);
printf("%f \n\n",copie->prix);
copie = copie->suivant;
}
}

// Fonction SUPPRIMER :
pointeur_elm supprimer(pointeur_elm pt)
{
pointeur_elm sup;
char numcli[8];
char pause;

// Affiche tous les éléments du fichier chargé :
printf("Voici la liste de toutes les commandes :\n");
afficher(pt);

// On demande à l'utilisateur quel client il souhaite supprimer :
printf("\nQuel client voulez-vous supprimer ?\n");
scanf("%s",numcli);
sup=pt;

while (strcmp(sup ->numcli,numcli)!=0 && (sup !=NULL))
{
sup=sup->suivant;
}
//Si le numéro saisi est null alors affichage d'un message d'erreur :
if (sup==NULL)
{
printf("Le numero saisi n'est pas correct");
pause = getchar();
}
else
{
//Il n'y a qu'un seul client ds le fichier (donc le précédent et le suivant sont nulls) :if(sup->precedent NULL && sup->suivant NULL)
{
free(sup);
}
else
{
//Celui qui se trouve avant le client saisi est null, donc le pointeur va au suivant :
if (sup->precedent == NULL)
{
pt=pt->suivant;
free (sup);
}
else
{
//Celui qui se trouve après le client saisi est null, donc le pointeur va au précédent :
if(sup->suivant == NULL)
{
pt=pt->precedent;
free (sup);
}
else
{
sup->precedent->suivant=sup->suivant;
sup->suivant->precedent=sup->precedent;
free (sup);
}
}
}
printf("\nVoici la nouvelle liste des commandes :\n");
afficher(pt);
}return(pt);
}

// Fonction MODIFIER :
pointeur_elm modifier(pointeur_elm pt)
{
pointeur_elm modif;
char numcli[8];
int trouve = 0;
int numero1;
modif = pt;

//Affiche tous les éléments du fichier chargé :
printf("Voici la liste de toutes les commandes :\n");
afficher(pt);

do{
printf("Quel client voulez-vous modifier ?\n");
scanf("%s",numcli);

// Boucle qui compare si le numcli saisi est <> de 0 et n'est pas Null :
while(strcmp(modif->numcli,numcli)!=0 && modif->suivant!=NULL)
{
modif=modif->suivant;
trouve = 1;
}
// Si le numcli saisi est null ou = à 0 alors affiche message d'erreur :
if(trouve == 1)
{
printf("Le numero saisi n'est pas correct\n");
}

// Sinon affiche le menu des modifications :
else
{
do{
printf("\nQue voulez-vous modifier ?\n");

// MENU POUR DEMANDER QUELLES MODIFICATIONS EFFECTUER :

printf("\n\t MENU DE MODIFICATION \n");
printf(" \n");
printf("1. Modifier le numero du client\n");
printf("2. Modifier la quantite de la commande\n");
printf("3. Modifier le prix unitaire de la commande\n");
printf("4. Fin Modifications\n");
printf("\n");
printf("Choisissez votre menu :\n");
fflush(stdin);
scanf("%d",&numero1);

switch(numero1)
{
case 1 : printf ("\nNouveau numero de client : ");
scanf("%s",&(modif->numcli));
break;
case 2 : printf("Nouvelle quantite de la commande : ");
scanf("%d",&(modif->quantite));
break;
case 3 : printf("Nouveau prix unitaire de la commande : ");
scanf("%f",&(modif->prix));
break;
}
}while(numero1 != 4);
}
// on remet la variable trouve à 0 :
trouve = 0;
//Modif reçoit pt (le premier pointeur) :
modif = pt;
fflush(stdin);

}while(numero1 != 4);

return(pt); // retourne le pointeur
}

// Fonction TRIER (par la méthode du quicksort):

// Pour l'instant elle ne retourne rien : A MODIFIER!!!
pointeur_elm trier(pointeur_elm pt)
{
char inferieur, superieur, pivot;
int p,i,j;

if (inferieur > superieur)
{
pivot=pivot->inferieur;
i=i->inferieur + 1;
j=j->superieur;
}
do{
if (i<=pivot)
{
i=i+1;
}
else
{
permut(i,j);
j=j-1;
}
}while(i<=j);
permut(inferieur, j);
p=p->j;
return(pt);
}

/*
// Fonction ENREGISTRER :
pointeur_elm enregistrer(pointeur_elm pt)
void enregistrer(pointeur_elm pt, char *dir)

{
pointeur_elm copie;
copie=pt;

printf("\nVoici la liste de toutes les commandes :\n");
while (copie != NULL)
{
// Rajouter un fprintf !!!
printf("%s \t",copie->numcli);
printf("%d \t",copie->quantite);
printf("%f \n\n",copie->prix);
copie = copie->suivant;
}
}
*/

// Fonction QUITTER :
void quitter(void)
{
printf("\nFERMETURE DU PROGRAMME...\n\n");
exit(0);
}
Messages postés
6
Date d'inscription
jeudi 25 novembre 2004
Statut
Membre
Dernière intervention
20 septembre 2005

A oui, j'ai oublié de dire ke je travail avec Visual studio C++
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
1
bj

la façon que j'emploierai pour résoudre ce problème est for simple:

1 lecture du fichier (BFichierTxt)
en stockant chaque ligne dans une liste triée (BLBString qui hérite de BListeIndir et ce trouve ds le meme source)

2 enregistrer le résultat du toString dans le fichier.

tu trouveras ces ref ds mes sources

ce qui donne

{
BLBString rep(true,true);//trié, avec doublon
BString plomp;//var temporaire
try
{
BFichierTxt fic("datas.txt","rt");
while(1)

rep+=fic.litLigne();

}
catch(BException& e)
{
if(e.which()!=87)//End Of File
throw(e);
}
BFichierTxt fic("datas.txt","wt");
fic+=rep.toString("\n","","");
}

voilà
++
Magic Nono: l'informagicien! 8-)
MFC addicted tentant de s'en sortir
Messages postés
232
Date d'inscription
vendredi 9 janvier 2004
Statut
Membre
Dernière intervention
8 janvier 2005

salut,

voila comment j'aurais programmé ça ...
le header (qui contient tout, développement inline et généricité oblige) :
#ifndef _DATA_H
#define _DATA_H

#include <vector>
#include <string>
#include 
#include 
using namespace std;

class Data_struct
{
public:
    typedef float price_type;
    typedef int quantity_type;

    Data_struct(const string& s,price_type p,quantity_type q):num(s),price(p),quantity(q){}
    ~Data_struct(){}
    price_type get_price()const{return price;}
    quantity_type get_quantity()const{return quantity;}
    string get_num()const{return num;}
private:
    string num;
    price_type price;
    quantity_type quantity;

};

//---------------------------------------------------------------------------

template <class D,class S = vector<D*> >
class Data
{
public:
    typedef S data_type;
    Data();
    ~Data();
    void append_from_file(istream &);
    template <class Cmp> inline void dsort(const Cmp&);
    template <class Cmp> inline void dstable_sort(const Cmp&);

private:
    data_type d;
};

// tri quicksort libstdc++
template <class D,class S>
template <class Cmp>
inline void Data<D,S>::dsort(const Cmp& cmp)
{
    sort(d.begin(),d.end(),cmp);
}

// autre tri plus robuste, mais un peu moins performant.
template <class D,class S>
template <class Cmp>
inline void Data<D,S>::dstable_sort(const Cmp& cmp)
{
    stable_sort(d.begin(),d.end(),cmp);
}

template <class D,class S>
Data<D,S>::Data<D,S>()
{
}

template <class D,class S>
Data<D,S>::~Data<D,S>()
{
    typedef typename S::const_iterator CIT;
    for(CIT cit = d.begin();cit != d.end();++cit)
delete *cit;
}

// pas de controle d'erreurs sur les flux ...
template <class D,class S>
void Data<D,S>::append_from_file(istream& is)
{
    string s_tmp;
    Data_struct::price_type p_tmp;
    Data_struct::quantity_type q_tmp;
    Data_struct* data;
    while(is >> s_tmp)
    {
is >> p_tmp;
is >> q_tmp;
try
{
    data = new Data_struct(s_tmp,p_tmp,q_tmp);
}
catch(bad_alloc)
{
    cerr << "not enough memory !" << endl;
            return;
}
d.push_back(data);
    }
}

typedef Data<Data_struct> Datafile;

//---------------------------------------------------------------------------

class Compare_noclient
{
public:
    int operator()(const Data_struct* const d1,const Data_struct*  const d2)const {
return d1->get_num() < d2->get_num();
    }
};

class Compare_quantity
{
public:
    int operator()(const Data_struct* const  d1,const Data_struct* const d2)const {
return d1->get_quantity() < d2->get_quantity();
    }
};

class Compare_price
{
public:
    int operator()(const Data_struct* const d1,const Data_struct* const d2)const {
return d1->get_price() < d2->get_price();
    }
};
#endif


le main :
#include "header.hpp"
#include <fstream>
using namespace std;

int main(int argc,char** argv)
{
    Datafile d;
    ifstream f("toto.txt");
    d.append_from_file(f);
    //d.dsort(Compare_price()); //conpare en fonction du prix
    //d.dsort(Compare_quantity()); //compare en fonction de la quantité
    d.dsort(Compare_noclient()); //compare en fonction de numéro client
    return 0;
}

la conception peut encore etre amélioré, mais je pense que ça doit pouvoir suffire ...
j'ai testé le programme, ça fonctionne, en principe.
Messages postés
6
Date d'inscription
jeudi 25 novembre 2004
Statut
Membre
Dernière intervention
20 septembre 2005

Oh lala, alors chez moi ca ne marche pas du tt !!!
Mais ce que tu me donne comme code, Plus_plus_fab, c du code de VB non ?? enfin sur Microsoft visual Studio C++ 6.0, ca ne marche pas du tt !! En plus je dois utiliser mes noms de variables, ainsi ke mon pointeur (pointeur_elm pt)

Merci pour votre aide
Messages postés
232
Date d'inscription
vendredi 9 janvier 2004
Statut
Membre
Dernière intervention
8 janvier 2005

Dans ton premier post, tu évoque C++, je te le donne en C++ ...

"c du code de VB non ??"
tu m'insulte la, non ?

muni toi d'un compilateur C++ digne de ce nom, ce code fonctionne et compile.
Maintenant, si c'est pour un exercice scolaire, que tu dois programmer en C, avec tes noms de variables, listes chainées, ... c'est un autre exercice pas plus difficile, mais j'ai plus le temps.
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
On va remercier plus_plus_fab pour le travail fourni dans le but d'aider et ensuite rassurer miss_aurel_8 sur son compilo qui va impec dans le boulot car c'est le plus rependu.

ciao...
BruNews, MVP VC++
Messages postés
232
Date d'inscription
vendredi 9 janvier 2004
Statut
Membre
Dernière intervention
8 janvier 2005

un compilateur C++ digne de ce nom doit etre capable de compiler le code que j'ai écrit. C'est tout ce que j'en dis BruNews.
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
1
logique shadock peut etre, mais pourquoi tout simplement ne pas faire simple et court??

cf + haut
++
Magic Nono