Chercher un string dans un fichier texte ?

Résolu
chtitpierre78 Messages postés 30 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 29 décembre 2008 - 25 nov. 2008 à 10:59
cs_Ballesteros Messages postés 11 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 27 novembre 2010 - 26 nov. 2010 à 09:48
Bonjour,

Je développe actuellement un outils en C++ (VisualC++) qui me permet de comparer 2 fichiers textes (.txt) d'environ 4Mo chacun (soit environ 60000 lignes de textes), le tout sous Windows. Le premier fichier texte liste la totalité des fichiers de mon DD, avec leurs tailles, leur date d'écriture et leurs chemin complet, tout ceci à un instant N. Le second fichier, liste exactement la même chose, à un instant N+1.
Les fichiers sont de la forme :

c:\monchemin\mondossier\monssdossier\monfichier.extension;taille;datedecriture
c:\monchemin\mondossier1\monssdossier1\monfichier1.extension;taille;datedecriture
c:\monchemin\mondossier1\monssdossier2\monfichier2.extension;taille;datedecriture
...

Jusque la, ca va, le listing est très rapide, et trés efficace. Le probleme qui se pose maintenant est le suivant :
La comparaison de mes 2 fichiers est trés lente. Je vous pose rapidement mon algo de comparaison :

Lecture ligne 1 du fichier 2
Comparaison de la ligne 1 avec toutes les lignes du fichier 1
Si on ne trouve pas de ligne identique, on ecrit cette ligne dans un ficheir texte de sortie.

Lecture ligne 2 du fichier 2

Comparaison de la ligne 2 avec toutes les lignes du fichier 1

Si on ne trouve pas de ligne identique, on ecrit cette ligne dans un ficheir texte de sortie.

Et je continu comme ca en incrementant le numero de ligne du fichier 2.

Donc je compare chaque ligne de mon fichier 2, avec toutes les lignes de mon fichier 1.
Je comprend que ca prenne du temps, mais je dois absolument remedier à ca.

Voila mon code :

**************************************************************

void exclude (char *f1, char *f2)
{
    ifstream fichier2("2.txt");
    FILE *res;
    string ligne1;
    string ligne2;
    int cpt=0;
    bool test;

    res=fopen("res.txt","w");
    fprintf(res,"DIFFERENCES :\n\n");

    while(getline(fichier2,ligne2))
    {
        cout <<"\b\b\b\r" <<cpt++;
        test = true;
        ifstream fichier1("1.txt");

        while(getline(fichier1,ligne1))
        { 
            if(ligne2==ligne1)
            {
                test=true;
                break;
            }
            else
            {
                test=false;
            }
        }
        if(test==false)
        {
            fprintf(res,"%s\n",ligne2.c_str());
        }
    }
    fclose(res);
}

**************************************************************

Donc voila, je me tourne vers vous, afin de savoir si il n'existe pas un moyen plus rapide de comparer ces fichiers textes. Pour information, je tourne sous un gros PC, plutot bien equipé et d'apres mes calculs je suis a une moyenne d'analyse de 300 lignes ( de mon fichier 2 ) analaysées / minutes.

Cordialement

K. Pierre

7 réponses

BunoCS Messages postés 15475 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 avril 2024 103
26 nov. 2008 à 11:39
Eh non, il n'y a pas plus bas niveau de str(i)cmp, mise à part l'assembleur directement...
Le principe du checksum m'intéresse. Peux-tu m'en dire un peu plus?

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
3
BunoCS Messages postés 15475 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 avril 2024 103
25 nov. 2008 à 11:23
Salut,
Effectivement, la comparaison 1 à 1 est assez longue. Pourquoi ne pas ré-organiser ton fichier pour le mettre sous forme d'arbre par exemple? Tu limiterais ta zone de recherche, tu ne trouves pas?

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
0
chtitpierre78 Messages postés 30 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 29 décembre 2008
26 nov. 2008 à 11:34
Sur les conseils d'un forumeur, je me suis orienté vers un checksum.
La comparaison est effectivement plus rapide, mais ça reste tout de même très lent... :(
Je me demande donc si il n'existe pas un moyen plus rapide que "strcmp" ou "stricmp" afin de comparer 2 checksum format MD5 ?

Cordialement

K. Pierre
0
chtitpierre78 Messages postés 30 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 29 décembre 2008
26 nov. 2008 à 12:37
En fait, j'ai calculer le MD5 de chacune de mes lignes, ce qui réduit donc considérablement la taille des chaines à comparer. je me retrouve au finale avec des listes de MD5, qui sont en fait la signature de chacun de mes fichiers.
Ce qui donne en fait :

AVANT :
c:\monchemin\mondossier\monssdossier\monfichier.extension;taille;datedecriture
c:\monchemin\mondossier1\monssdossier1\monfichier1.extension;taille;datedecriture
...

APRES :
123456789ABCDEF123456789ABCDEF        // checksum de mon premier fichier
987654321ABCDEF987654321ABCDEF        // checksum de mon second fichier

Et je compare donc non plus les chemins, mais les MD5. C'est clairement plus rapide, mais pas assez encore.
Si il n'existe pas plus rapide que "strcmp", je ne sait vraiment pas vers quoi m'orienter.

Mon objectif final étant de de pouvoir lister les fichiers qui ont été modifié / ajouté sur mon disque dur.
Je me suis déjà orienter vers les API Windows type ReadDirectoryChangesW, mais ca me convient pas vraiment , je veux pas de quelque chose qui tourne en tache de fond 24/24.

Cordialement

K. Pierre

Ps : Si tu desires le code pour obtenir le md5, envoi moi un mp.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Ballesteros Messages postés 11 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 27 novembre 2010
25 nov. 2010 à 22:42
Dans les deux fichiers que tu compare, il semble y avoir une probabilité de correspondance énorme entre ta liste N et ta liste N+1. Dans ces conditions je pense qu'il serait utile pour toi de trier les md5, de façon à ne pas reparcourir les md5 déja testés. Mettons que tu teste les tableaux A et B, tu ne repartira pas de l'index 0 à chaque iteration de l'index de A, mais plutot du dernier index <A[i]. dans le meilleur des cas tu parcourera ton tableau A et B en (n). Dans tous les cas tu fera toujours mieux que du n², il faut absolument que tu tire profit de la similarité entre tes deux tableaux.
0
BunoCS Messages postés 15475 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 avril 2024 103
26 nov. 2010 à 09:18
@Ballesteros: merci de ta participation...mais le sujet a maintenant 2 ans (pile poil, tiens!) et il a certainement résolu son problème

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Rejoignez mon réseau professionnel sur Viadeo
0
cs_Ballesteros Messages postés 11 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 27 novembre 2010
26 nov. 2010 à 09:48
Ah oui quand même . Je crois qu'il y a un méchant bug alors puisque le sujet apparaissait dans les sujets les plus récents...étant du 25 novembre mais pas de la bonne année..

Désolé.
0
Rejoignez-nous