IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Rechercher des doublons dans un fichier de type csv


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par d�faut Une application qui fige lors d'un �v�nement sur la frame.
    Bonjour tout le monde,

    Je vais essayer de faire simple.
    Je d�veloppe une application sous wx-Devcpp.
    Objectif: rechercher des doublons de lignes dans un fichier de type csv.

    Voil� � quoi ressemble le fichier de donn�es:

    NOM;PRENOM;N�SECU;n�RUE;nom RUE;VILLE
    Someone;Jonathan;123456789012345;13;rue de l'�tang;Ici
    Somebody;S�bastien;123456789012344;1;avenue les bains;L� bas
    Someone;Jonathan;123456789012345;13;rue de l'�tang;Ici
    Dans le cas actuel, le fichier en question est ouvert, lu et stock� int�gralement dans un buffer allou� dynamiquement.
    Ensuite, pour l'instant, l'application parcourt lin�airement le buffer caract�re par caract�re � la recherche du champ le plus long.

    La taille du fichier � analyser semble �tre un obstacle:

    Avec un petit fichier de test, tout se passe bien.
    A partir d'environ 1Mo, l'application se met � fortement ralentir, et si par malheur la fen�tre perd le focus ou est d�plac�e, celle ci fige et ne r�pond
    plus.
    L'application fige �galement au bout d'un certain temps.


    Pensez vous qu'il soit bien de stocker tout un fichier en m�moire pour travailler avec le contenu ?
    (celui-ci pourra atteindre au maximum 50Mo) ?

    Merci d'avance pour votre aide.

  2. #2
    yan
    yan est d�connect�
    R�dacteur
    Avatar de yan
    Homme Profil pro
    Ing�nieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activit� : Ing�nieur expert
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par d�faut
    50 Mo oula t'es fou???
    non je d�conne c'est vraiment pas beaucoup 50 Mo...
    Si tu peut expliquer un peu plus ton algo et voir m�me un peu de code.
    On pourras surement t'aider

  3. #3
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    La bonne question est surtout de savoir ce que tu veux faire avec les doublons trouv�s...

    Si, comme on est tent� de le croire, le but est de supprimer les valeurs en double, l'une des solutions les plus simple pourrait, tout simplement,
    1. de cr�er une structure permettant de stocker les informations
    2. pr�voir l'op�rateur < pour cette structure (n�cessaire pour le tri des set et des map)
    3. lire les �l�ments un � un
    4. placer le �l�ments dans un set - voire, pourquoi pas, dans une map - parce que cela assure l'unicit� des �l�ment que le conteneur contient
    5. r��crire le contenu du set ou de la map apr�s lecture du fichier complet


    Si le but est diff�rent, d'autres solutions peuvent �tre envisag�es
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par d�faut
    L'objectif est juste de signaler tout ou partie des lignes redondantes.
    Je n'envisage pas de les supprimer, mais juste d'afficher un message avec le num�ro des lignes doublonn�es.


    Voici quelques extraits de code:
    • fonction pour ouvrir le fichier et stocker le contenu dans le buffer allou� dynamiquement (appel�e suite � l'�v�nement OK de la boite de dialogue d'ouverture de fichiers)


    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    void load_datafile()
    {
        FILE *fd;
        file_fullname = wxFileSelector("Choose a file to open");
     
        long sizeofile=0;  // datafile length
        long result;  // fucking variable to count the number of effective readed caracters in datafile!
     
     
        // if the openfile Dialog returned something true
        if ( !file_fullname.empty() )
        {
            // get full pathfile in char*
            const char *pFileName = file_fullname.mb_str();
            // and then try to open the file in READ ONLY and get a valid descriptor!
            if((fd = fopen(pFileName,"rb")) != NULL)
            {
                /**** get file size *****/
                fseek( fd, 0L, SEEK_END );
                long endPos = ftell( fd );
                sizeofile = endPos;
                wxLogStatus("longueur fichier de données = %ld octets", sizeofile);
                rewind(fd);
     
                /**** get file content *****/
                // allocate dynamic memory to get this...
                buffer = (char*) malloc( sizeof(char) * sizeofile);
     
                // copy the file into the buffer:
                result = fread (buffer,1,sizeofile,fd);
                if (result != sizeofile)
                {
                    wxLogMessage("Erreur de lecture dans le fichier!");
                    fflush(stdin);
                    getchar();
                    exit(-1);
                }
     
                loaded=true;    // fichier chargé...
                fclose(fd);
            }
            else    // should happends if open fails
            {
                loaded=false;    // fichier non chargé...
                wxLogMessage("Impossible d'ouvrir le fichier: %s",pFileName);
                // then exit from "Mnuopen1007Click" ...
            }
     
     
        }
        else
        {
            wxLogMessage("Pas de fichier ouvert!");
        }
    }


    • Voici la fonction qui d�termine la longueur du plus grand champ dans le fichier csv (appel�e lors d'un clic sur le bouton "analyser")



    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    int identify_fields()
    {
     
        int i=0;
     
        int field_len;      // tmp field length
        int longest_field;  // size of the longest field (to determine how much allocate for a field) --> of course there is no optimisation of memory!!!
     
     
        // just a security (file must have been loaded, if not leave the function)
        if (loaded!=true)
            return -1;
     
     
     
        /*** Get the longest field in the file (for static size fields length allocation) ***/
     
        int aze=0;
     
        field_len=0;
        longest_field=0;
        for (i=0;i<(int)strlen(buffer);i++)
        {
                    // if data concern any of field content...
            if (buffer[i]!=';' && buffer[i]!='\n')
                field_len++;
            else    // otherwise compare this calculated value with the longest_field one, and if greater, update...
            {
                if (field_len > longest_field)
                    longest_field = field_len;
                field_len=0;    // of course, reset the field_len count!
            }
     
            aze++;
            if (aze>9)
            {
                wxLogStatus("Lu %d / %d", i, (int)strlen(buffer) );
                aze=0;
            }
     
        }
        wxLogMessage("champ le plus grand vaut %d caracteres", longest_field);
     
     
        return 0;
    }

    Ces 2 fonctions sont d�clar�es dans le m�me fichier (csv-Parser.cpp).
    La variable buffer est d�clar�e en global.

    Pour l'algo, actuellement il peut ressembler � �a:

    SI un fichier est ouvert
    d�terminer sa taille
    allouer dynamiquement de la m�moire pour contenir le fichier
    FIN SI

    SI click sur Bouton "Analyser"
    TANT QUE (pas fin de fichier)
    {
    si (carat�re lu <> ';' et caract�re lu <> '\n')
    incr�menter taille temporaire du champ
    sinon
    {
    si (taille temporaire > taille max)
    {
    taille max = taille temporaire
    }
    taille temporaire = 0
    }

    afficher p�riodiquement dans la barre d'�tat l'octet en cours de lecture
    }
    FIN TANT QUE

    enfin afficher la taille du champ le plus long trouv�
    FIN SI

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par d�faut Application d�velopp�e en wx-Devcpp qui fige
    Bonjour, me revoil�!
    J'ai r�solu une partie de mon probl�me en faisant une allocation dynamique de m�moire en utilisant new et delete plut�t que malloc et free.

    Le positif: l'application r�ussit maintenant � balayer tout le fichier sans se bloquer.

    Le n�gatif: Lorsque celle ci est en cours et parcourt le fichier, ne surtout pas cliquer sur sa fen�tre, tenter de la d�placer ou m�me faire autre chose comme aller par exemple lire ses mails: celle ci fige et y apparait en haut � gauche "ne r�pond pas".

    Vous avez une id�e?

    Pour info, c'est � l'�xecution de cette boucle qui peut durer tr�s longtemps (d�pend de la taille du fichier) que survient le probl�me.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
        field_len=0;
        longest_field=0;
        for (i=0;i<(int)strlen(buffer);i++)
        {
            // si la donnée n'est pas un délimiteur
            if (buffer[i]!=';' && buffer[i]!='\n')
                field_len++;
            else    // alors fin du champ n°X
            {
                if (field_len > longest_field)
                    longest_field = field_len;
                field_len=0;
            }
     
            aze++;
            if (aze>9)
            {
                wxLogStatus("Lu %d / %d", i, (int)strlen(buffer) );
                aze=0;
            }
     
        }
        wxLogMessage("champ le plus grand vaut %d caracteres", longest_field);
    Merci � vous koala01 et Mongaulois pour vos r�ponses.
    (D�s que ce bug sera r�solu, je passerai � l'�tape stockage des donn�es)

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par d�faut
    Re bonjour,

    J'ai trouv� la solution au probl�me

    Il faut g�rer les �v�nements, ou plut�t donner un peu de temps au syst�me pour qu'il puisse le faire!

    Pour cel�, l'appel de la fonction membre Yield(); est indispensable avant d'afficher quelque chose dans le status control.


    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    aze++;
    if (aze>9)
    {
          // use of Yield member to avoid freezes when something is displayed...
          pointeur->Yield(false);
          wxLogStatus("Lu %d / %d", i, (int)strlen(buffer) );
          aze=0;
    }

    Cette page m'a beaucoup aid�:
    http://docs.wxwidgets.org/stable/wx_...s.html#wxyield

    Il ne faut juste pas oublier d'initialiser le pointeur de classe wxApp avant l'appel de Yield() via:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    wxApp *pointeur = new wxApp;

    Bon codage!

  7. #7
    Membre �m�rite
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    D�tails du profil
    Informations personnelles :
    �ge : 50
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Par d�faut
    pour moi il faudrait mettre le fichier dans un gros char*
    puis n'utiliser que des pointeurs sur cette zone memoire (des string a la C)
    et utiliser des map<char*,char*> avec une fonction de comparaison pour les char*

    donc tu n'utiliseras que la memoire necessaire pour le fichier et pas de copie de string a gogo.

    ps: je l'ai deja fait et ca marche vraiment super (j'avais aussi implement� la methode basique, je lis le fichier et je cree ma structure de donn�e avec std::string, pas performante du tout)

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 0
    Dernier message: 04/11/2008, 21h46
  2. Rechercher des donn�es dans un fichier txt
    Par joboy84 dans le forum Langage
    R�ponses: 5
    Dernier message: 11/06/2008, 15h00
  3. recherche des doublons dans une hash
    Par Jasmine80 dans le forum Langage
    R�ponses: 4
    Dernier message: 29/01/2007, 11h51
  4. R�ponses: 3
    Dernier message: 16/10/2005, 11h03
  5. recherche de doublons dans un fichier texte
    Par portu dans le forum Algorithmes et structures de donn�es
    R�ponses: 3
    Dernier message: 07/10/2003, 14h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo