Partage
  • Partager sur Facebook
  • Partager sur Twitter

Je n'arrive pas à trier les données de mon fichier txt

je suis occupé là dessus depuis ce matin

    11 mai 2008 à 15:14:53

    Bonjour tout le monde,

    J'ai une méthode qui permet de trier :

    int CChaine::Comparer(const CGenerique& Autre, long TypeComparaison) const
    {
    	switch (TypeComparaison)
    	{
    	case ComparaisonPourUnicite:
    		return strcmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriCroissantStrict:
    		return strcmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriDecroissantStrict:
    		return -strcmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriCroissantNonStrict:
    		return stricmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriDecroissantNonStrict:
    		return -stricmp(Chaine(),((const CChaine&)Autre).Chaine());
    	}
    	return 0;
    }
    

    case ComparaisonPourUnicite: s'est pour gérer l'unicité, s'est comme un filtre, les lignes ou les mots du fichier texte ne sont pas chargés ni affichés deux fois, ça, ça fonctionne.

    Par contre, le tri ne fonctionne pas.

    if(TypeComparaison == 1) return m_NomProduit.Comparer(m_NomProduit,Comparaison_TriCroissantNonStrict);
    

    Je pense que la façon de trier est par rapport à ceci :

    void CTabProduits::Trier()
    {
    CTableauGenerique::Trier(1);
    }

    et j'ai aussi ceci :

    long CProduit::NombreClesDeTri() const
    {
    	return 1;
    }
    


    et bien si j'ai ces produits dans mon fichier txt :


    Citation : beegees

    poulet 60
    carotte 10
    huile d'olive 70
    tomate 20
    poivron 40
    oeuf 20
    lavande 50
    truffe 100
    piment 80
    sauge 90
    carotte 1000
    12
    ail -10

    J'obtiens ceci :

    Citation : apèrs triage

    oeuf 20
    carotte 10
    huile d'olive 70
    tomate 20
    poivron 40
    poulet 60
    lavande 50
    truffe 100
    piment 80
    sauge 90

    par contre ces trois articles-ci ne sont pas chargés car les ils n'ont pas passés les tests de validités (doublon, strlen(chaine) >0 et Prix >0 :

    Citation : beegees

    carotte 1000
    12
    ail -10


    Je me demande dans quel ordre s'est trié :?

    Voici les classes concernées par le tri :


    #include <BasicConsole.h>
    #include "produits.h"
    
    //////////////
    // CProduit //
    /////////////
    
    CProduit::CProduit()
    :m_PP(0)
    {
    }
    
    CProduit::CProduit(const CProduit& Source)
    :CGenerique(Source),m_NomProduit(Source.m_NomProduit),m_PP(Source.m_PP)
    {
    }
    
    CProduit::CProduit(const char* UnNom, int UnPrix)
    :m_PP(0) //on recopie la même chose que dans le constructeur spécifique
    {	
    	SetNomProduit(UnNom);
    	SetPrixProduit(UnPrix);
    }
    
    CProduit::~CProduit()
    {
    }
    
    bool CProduit::SetNomProduit(const char* UnNom)
    {
    	if((strlen(UnNom)<1)&&(UnNom==NULL))return false;
    	return m_NomProduit.Chaine(UnNom);
    }
    
    bool CProduit::SetPrixProduit(int UnPrix)
    {
    	if(UnPrix<1)return false;
    	m_PP = UnPrix;
    	return true;
    }
    
    const char* CProduit::GetNomProduit() const
    {
    	return m_NomProduit.Chaine();
    }
    
    int CProduit::GetPrixProduit() const
    {
    	return m_PP;
    }
    
    CGenerique* CProduit::Cloner() const
    {
    	return new CProduit(*this);
    }
    
    bool CProduit::EstValide() const
    {
    	return(strlen(GetNomProduit())>1)&&(GetPrixProduit()>1);
    }
    
    bool CProduit::GereUnicite() const
    {
    	return true;
    }
    
    
    int CProduit::Comparer(const CGenerique& Autre, long TypeComparaison) const
    {
    	if(TypeComparaison == 0) return m_NomProduit.Comparer(((const CProduit&)Autre).m_NomProduit,Comparaison_TriCroissantNonStrict);
    	if(TypeComparaison == 1) return m_NomProduit.Comparer(m_NomProduit,Comparaison_TriCroissantNonStrict);
    	
    }
    
    long CProduit::NombreClesDeTri() const
    {
    	return 1;
    }
    
    //////////////////
    // CTabProduits //
    //////////////////
    
    CTabProduits::CTabProduits()
    :CTableauGenerique(CProduit())
    {
    }
    
    CTabProduits::CTabProduits(const CTabProduits& Source)
    :CTableauGenerique(Source)
    {
    }
    
    CTabProduits::~CTabProduits()
    {
    }
    
    CGenerique* CTabProduits::Cloner() const
    {
    	return new CTabProduits(*this);
    }
    
    CProduit& CTabProduits::Element(long Indice) const
    {
    	return (CProduit&)CTableauGenerique::Element(Indice);
    }
    
    long CTabProduits::Indice(const char* UnNom) const
    {
    	return CTableauGenerique::Indice(CProduit(UnNom,1));
    }
    
    bool CTabProduits::Ajouter(const CProduit& Modele)
    {
    	return CTableauGenerique::Ajouter(Modele);
    }
    
    /////////////////////////
    // CTraitementProduits //
    /////////////////////////
    
    CTraitementProduits::CTraitementProduits()
    {
    }
    
    CTraitementProduits::~CTraitementProduits()
    {
    }
    
    bool CTraitementProduits::Charger(const char* NomFichier)
    {
    	CChargeurFichierTexte	Chargeur;
    
    	if (!Chargeur.Charger(NomFichier,'\t',FctnTraiterLigne,this)) return false;
    	m_Produits.Trier();
    	
    /*	// Affichage des deux tableaux*/
    	for (long n=0; n < m_Produits.Nombre(); n++)
    	{
    		CProduit& P = m_Produits.Element(n);
    		printf("%s \t\t  %ld\n",P.GetNomProduit(),P.GetPrixProduit());
    	}
    	
    	return true;
    }
    
    bool CTraitementProduits::FctnTraiterLigne(const CChargeurFichierTexte& Chargeur, void* Contexte)
    {
    	return ((CTraitementProduits*)Contexte)->TraiterLigne(Chargeur);
    }
    
    bool CTraitementProduits::TraiterLigne(const CChargeurFichierTexte& Chargeur)
    {
    	if(Chargeur.NombreChamps() == 2) m_Produits.Ajouter(CProduit(Chargeur.Champs(0),atol(Chargeur.Champs(1))));
    	return true;
    }
    
    void CTabProduits::Trier()
    {
    	CTableauGenerique::Trier(1);
    }
    

    #include <BasicConsole.h>
    #include "chaine.h"
    
    
    ////////////////////
    // Classe CChaine //
    ////////////////////
    
    CChaine::CChaine()
    :m_Chaine(NULL)
    {
    }
    
    CChaine::CChaine(const CChaine& Source)
    :m_Chaine(NULL)
    {
    	Chaine(Source.m_Chaine);
    }
    
    CChaine::CChaine(const char* UneChaine)
    :m_Chaine(NULL)
    {
    	Chaine(UneChaine);
    }
    
    CChaine::~CChaine()
    {
    	Vider();
    }
    
    bool CChaine::GereUnicite() const
    {
    	return true;
    }
    
    long CChaine::NombreClesDeTri() const
    {
    	return 4;
    }
    
    CGenerique* CChaine::Cloner() const
    {
    	return new CChaine(*this);
    }
    
    bool CChaine::EstValide() const
    {
    	return true;
    }
    
    int CChaine::Comparer(const CGenerique& Autre, long TypeComparaison) const
    {
    	switch (TypeComparaison)
    	{
    	case ComparaisonPourUnicite:
    		return strcmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriCroissantStrict:
    		return strcmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriDecroissantStrict:
    		return -strcmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriCroissantNonStrict:
    		return stricmp(Chaine(),((const CChaine&)Autre).Chaine());
    	case Comparaison_TriDecroissantNonStrict:
    		return -stricmp(Chaine(),((const CChaine&)Autre).Chaine());
    	}
    	return 0;
    }
    
    void CChaine::Vider()
    {
    	if (m_Chaine != NULL)
    	{
    		free(m_Chaine);
    		m_Chaine = NULL;
    	}
    }
    
    bool CChaine::Chaine(const char* UneChaine)
    {
    	if (UneChaine == NULL) return false;
    	void* Nouveau = realloc(m_Chaine,(strlen(UneChaine)+1)*sizeof(char));
    	if (Nouveau == NULL) return false;
    	m_Chaine = (char*)Nouveau;
    	strcpy(m_Chaine,UneChaine);
    	return true;
    }
    
    bool CChaine::Concatener(const char* UneChaine)
    {
    	if (UneChaine == NULL) return false;
    	long Taille = strlen(Chaine());
    	void* Nouveau = realloc(m_Chaine,(Taille+strlen(UneChaine)+1)*sizeof(char));
    	if (Nouveau == NULL) return false;
    	m_Chaine = (char*)Nouveau;
    	strcpy(m_Chaine+Taille,UneChaine);
    	return true;
    }
    
    bool CChaine::Concatener(long NombreFois, char Caractere)
    {
    	if (NombreFois < 1) return false;
    	long Taille = strlen(Chaine());
    	void* Nouveau = realloc(m_Chaine,(Taille+NombreFois+1)*sizeof(char));
    	if (Nouveau == NULL) return false;
    	m_Chaine = (char*)Nouveau;
    	while (NombreFois-- > 0) m_Chaine[Taille++] = Caractere;
    	m_Chaine[Taille] = 0;
    	return true;
    }
    
    const char* CChaine::Chaine() const
    {
    	return (m_Chaine != NULL) ? m_Chaine : "";
    }
    
    bool CChaine::EstNull() const
    {
    	return (m_Chaine == NULL);
    }
    
    bool CChaine::EstVide() const
    {
    	return (m_Chaine == NULL) || (m_Chaine[0] == 0);
    }
    
    
    ////////////////////////////
    // Classe CChaineComposee //
    ////////////////////////////
    
    CChaineComposee::CChaineComposee()
    :m_NbrChamps(0),m_Champs(NULL)
    {
    }
    
    CChaineComposee::CChaineComposee(const CChaineComposee& Source)
    :CChaine(Source),m_NbrChamps(0),m_Champs(NULL)
    {
    	if (Source.m_NbrChamps > 0)
    	{
    		m_Champs = (char**)malloc(Source.m_NbrChamps*sizeof(char*));
    		if (m_Champs != NULL)
    		{
    			m_NbrChamps = Source.m_NbrChamps;
    			for (long n=0; n < Source.m_NbrChamps; n++)
    			{
    				long PosRel = Source.m_Champs[n] - Source.m_Champs[0];
    				m_Champs[n] = ((char*)Chaine()) + PosRel;
    			}
    		}
    	}
    }
    
    CChaineComposee::CChaineComposee(const char* UneChaine, char UnSeparateur)
    :CChaine(UneChaine),m_NbrChamps(0),m_Champs(NULL)
    {
    	Decomposer(UnSeparateur);
    }
    
    CChaineComposee::~CChaineComposee()
    {
    	if (m_Champs) free(m_Champs);
    }
    
    bool CChaineComposee::GereUnicite() const
    {
    	return false;
    }
    
    long CChaineComposee::NombreClesDeTri() const
    {
    	return 0;
    }
    
    CGenerique* CChaineComposee::Cloner() const
    {
    	return new CChaineComposee(*this);
    }
    
    int CChaineComposee::Comparer(const CGenerique& Autre, long TypeComparaison) const
    {
    	return 0;
    }
    
    long CChaineComposee::NombreChamps() const
    {
    	return m_NbrChamps;
    }
    
    const char* CChaineComposee::Champs(long Indice) const
    {
    	return ( (Indice >= 0) && (Indice < m_NbrChamps) ) ? m_Champs[Indice] : "";
    }
    
    bool CChaineComposee::Definir(const char* UneChaine, char UnSeparateur)
    {
    	if (!Chaine(UneChaine)) return false;
    	return Decomposer(UnSeparateur);
    }
    
    bool CChaineComposee::Decomposer(char UnSeparateur)
    {
    	m_NbrChamps = 0;
    	char* Texte = (char*)Chaine();
    	if (Texte == NULL) return false;
    	void* Nouveau = realloc(m_Champs,1*sizeof(char*));
    	if (Nouveau == NULL)
    	{
    		if (m_Champs)
    		{
    			free(m_Champs);
    			m_Champs = NULL;
    		}
    		return false;
    	}
    	m_Champs = (char**)Nouveau;
    	m_Champs[m_NbrChamps] = Texte;
    	m_NbrChamps++;
    	while (true)
    	{
    		char* Delimiteur = strchr(Texte,UnSeparateur);
    		if (Delimiteur == NULL) return true;
    		*Delimiteur = 0;
    		Texte = Delimiteur + 1;
    		void* Nouveau = realloc(m_Champs,(m_NbrChamps+1)*sizeof(char*));
    		if (Nouveau == NULL) return false;
    		m_Champs = (char**)Nouveau;
    		m_Champs[m_NbrChamps] = Texte;
    		m_NbrChamps++;
    	}
    }
    
    
    //////////////////////////////////
    // Classe CChargeurFichierTexte //
    //////////////////////////////////
    
    CChargeurFichierTexte::CChargeurFichierTexte()
    {
    }
    
    CChargeurFichierTexte::CChargeurFichierTexte(const CChargeurFichierTexte& Source)
    :CChaineComposee(Source)
    {
    }
    
    CChargeurFichierTexte::~CChargeurFichierTexte()
    {
    }
    
    CGenerique* CChargeurFichierTexte::Cloner() const
    {
    	return (CGenerique*)((void*)new CChargeurFichierTexte(*this));
    }
    
    bool CChargeurFichierTexte::Charger(const char* NomFichier, char UnSeparateur, bool (* FctnTraiterLigne)(const CChargeurFichierTexte&, void*), void* Contexte)
    {
    	const long		TailleLigne = 500;
    	char			Ligne[TailleLigne+1];
    	FILE*			Fichier;
    
    	if ( (NomFichier == NULL) || (*NomFichier == 0) ) return false;
    	Fichier = fopen(NomFichier,"rt");
    	if (Fichier == NULL) return false;
    	while (fgets(Ligne,TailleLigne,Fichier) != NULL)
    	{
    		long i = strlen(Ligne);
    		if ( (i > 0) && (Ligne[i-1] == '\n') ) Ligne[i-1] = 0;
    		if (Definir(Ligne,'\t'))
    		{
    			if (!FctnTraiterLigne(*this,Contexte))
    			{
    				fclose(Fichier);
    				return false;
    			}
    		}
    	}
    	fclose(Fichier);
    	return true;
    }
    


    Sauriez-vous m'aider svp ?

    Je vous en remercie d'avance.

    beegees
    • Partager sur Facebook
    • Partager sur Twitter
      11 mai 2008 à 15:58:01

      Euh... je peux voir ta méthode de tri?
      • Partager sur Facebook
      • Partager sur Twitter
        11 mai 2008 à 16:04:52

        Salut,

        Merci pour ta réponse.

        Edit : voici le code demandé :
        void CTableauGenerique::Trier(long TypeComparaison)
        {
        	if ( (m_Nombre >= 2) && (TypeComparaison >= 1) && (TypeComparaison <= m_Poubelle->NombreClesDeTri()) )
        	{
        		m_TypeComparaison = TypeComparaison;
        		qsort(m_Tableau,m_Nombre,sizeof(CGenerique*),Comparer);
        		m_TypeComparaison = -1;
        	}
        }
        


        et voici le code de la classe generique :

        #include <BasicConsole.h>
        #include <search.h>
        #include "generique.h"
        
        
        ///////////////////////
        // Classe CGenerique //
        ///////////////////////
        
        CGenerique::CGenerique()
        :m_Conteneur(NULL)
        {
        }
        
        CGenerique::CGenerique(const CGenerique& Source)
        :m_Conteneur(NULL)
        {
        }
        
        CGenerique::~CGenerique()
        {
        }
        
        bool CGenerique::GereUnicite() const
        {
        	return false;
        }
        
        long CGenerique::NombreClesDeTri() const
        {
        	return 0;
        }
        
        CGenerique* CGenerique::Cloner() const
        {
        	return new CGenerique(*this);
        }
        
        bool CGenerique::EstValide() const
        {
        	return true;
        }
        
        int CGenerique::Comparer(const CGenerique& Autre, long TypeComparaison) const
        {
        	return 0;
        }
        
        CTableauGenerique* CGenerique::Conteneur() const
        {
        	return m_Conteneur;
        }
        
        void CGenerique::DefinirConteneur(CTableauGenerique* Tableau)
        {
        	m_Conteneur = Tableau;
        }
        
        
        //////////////////////////////
        // Classe CTableauGenerique //
        //////////////////////////////
        
        CTableauGenerique::CTableauGenerique(const CGenerique& ModelePoubelle)
        :m_Poubelle(NULL),m_Nombre(0),m_Tableau(NULL),m_TypeComparaison(-1)
        {
        	m_Poubelle = ModelePoubelle.Cloner();
        	m_Poubelle->DefinirConteneur(this);
        }
        
        CTableauGenerique::CTableauGenerique(const CTableauGenerique& Source)
        :m_Poubelle(NULL),m_Nombre(0),m_Tableau(NULL),m_TypeComparaison(-1)
        {
        	m_Poubelle = Source.m_Poubelle->Cloner();
        	for (long n=0; n < Source.m_Nombre; n++) Ajouter(Source.Element(n));
        }
        
        CTableauGenerique::~CTableauGenerique()
        {
        	Vider();
        	delete m_Poubelle;
        }
        
        CGenerique* CTableauGenerique::Cloner() const
        {
        	return new CTableauGenerique(*this);
        }
        
        long CTableauGenerique::Nombre() const
        {
        	return m_Nombre;
        }
        
        CGenerique& CTableauGenerique::Element(long Indice) const
        {
        	return ((Indice >= 0) && (Indice < m_Nombre)) ? *(m_Tableau[Indice]) : *m_Poubelle;
        }
        
        long CTableauGenerique::Indice(const CGenerique& ModeleRecherche) const
        {
        	if ( (m_Nombre == 0) || (!m_Poubelle->GereUnicite()) || (!ModeleRecherche.EstValide()) ) return -1;
        	const CGenerique* Recherche = &ModeleRecherche;
        	unsigned int n = m_Nombre;
        	((CTableauGenerique*)this)->m_TypeComparaison = ComparaisonPourUnicite;
        	CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
        	((CTableauGenerique*)this)->m_TypeComparaison = -1;
        	return (Trouve != NULL) ? Trouve - m_Tableau : -1;
        }
        
        void CTableauGenerique::Vider()
        {
        	if (m_Tableau != NULL)
        	{
        		for (long n=0; n < m_Nombre; n++) delete m_Tableau[n];
        		free(m_Tableau);
        		m_Tableau = NULL;
        		m_Nombre = 0;
        	}
        }
        
        bool CTableauGenerique::Ajouter(const CGenerique& ModeleAAjouter, bool RetourEnCasDeDoublon)
        {
        	if (!ModeleAAjouter.EstValide()) return false;
        	if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
        	void* Nouveau = realloc(m_Tableau,(m_Nombre+1)*sizeof(CGenerique*));
        	if (Nouveau == NULL) return false;
        	m_Tableau = (CGenerique**)Nouveau;
        	CGenerique* AAjouter = ModeleAAjouter.Cloner();
        	if (!AAjouter->EstValide())
        	{
        		delete AAjouter;
        		return false;
        	}
        	m_Tableau[m_Nombre] = AAjouter;
        	m_Tableau[m_Nombre]->DefinirConteneur(this);
        	m_Nombre++;
        	return true;
        }
        
        bool CTableauGenerique::Supprimer(long Indice)
        {
        	if ( (Indice < 0) || (Indice >= m_Nombre) ) return false;
        	delete m_Tableau[Indice];
        	if (Indice < (m_Nombre-1)) memmove(m_Tableau+Indice,m_Tableau+(Indice+1),(m_Nombre-1-Indice)*sizeof(CGenerique*));
        	realloc(m_Tableau,(m_Nombre-1)*sizeof(CGenerique*));
        	m_Nombre--;
        	return true;
        }
        
        void CTableauGenerique::Trier(long TypeComparaison)
        {
        	if ( (m_Nombre >= 2) && (TypeComparaison >= 1) && (TypeComparaison <= m_Poubelle->NombreClesDeTri()) )
        	{
        		m_TypeComparaison = TypeComparaison;
        		qsort(m_Tableau,m_Nombre,sizeof(CGenerique*),Comparer);
        		m_TypeComparaison = -1;
        	}
        }
        
        /*static*/int CTableauGenerique::Comparer(const void* p1, const void* p2)
        {
        	const CGenerique* o1 = *((const CGenerique**)p1);
        	const CGenerique* o2 = *((const CGenerique**)p2);
        	return o1->Comparer(*o2,o2->Conteneur()->m_TypeComparaison);
        }
        


        Voici plus d'info :

        Citation : Prof

        en permettant le tri par rapport à un ou plusieurs membres servant de clé(s) de tri, il faut réécrire les méthodes long NombreClesDeTri() const afin qu'elle puisse retourner le nombre de clés de tri supportées et int Comparer(const CGenerique& Autre, long TypeComparaison) const afin d'implémenter la (ou les) comparaison(s) nécessaire(s) au(x) tri(s) ((TypeComparaison >= 1) et (TypeComparaison <= NombreClesDeTri))



        Merci encore pour ton aide.

        beegees
        • Partager sur Facebook
        • Partager sur Twitter

        Je n'arrive pas à trier les données de mon fichier txt

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown