Trier un fichier.txt, avec des pointeurs par QuickSort
miss_aurel_8
Messages postés6Date d'inscriptionjeudi 25 novembre 2004StatutMembreDernière intervention20 septembre 2005
-
25 nov. 2004 à 21:35
magic_Nono
Messages postés1878Date d'inscriptionjeudi 16 octobre 2003StatutMembreDernière intervention16 mars 2011
-
29 nov. 2004 à 08:51
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.
miss_aurel_8
Messages postés6Date d'inscriptionjeudi 25 novembre 2004StatutMembreDernière intervention20 septembre 2005 26 nov. 2004 à 09:55
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
//
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();
// 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);
// 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;
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);
}
plus_plus_fab
Messages postés232Date d'inscriptionvendredi 9 janvier 2004StatutMembreDernière intervention 8 janvier 2005 27 nov. 2004 à 14:02
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.
miss_aurel_8
Messages postés6Date d'inscriptionjeudi 25 novembre 2004StatutMembreDernière intervention20 septembre 2005 28 nov. 2004 à 12:35
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)
plus_plus_fab
Messages postés232Date d'inscriptionvendredi 9 janvier 2004StatutMembreDernière intervention 8 janvier 2005 28 nov. 2004 à 14:30
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.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 28 nov. 2004 à 14:50
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.