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 :

Aide pour réalisation programme de recherche fichiers en doubles


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Par défaut Aide pour réalisation programme de recherche fichiers en doubles
    Bonsoir, suite à une autre discussion, j'ouvre celle-ci pour demander des avis quant à la conception d'un programme de recherche de doublons de fichiers.

    En préambule, je sais que de tels programmes existent et je ne cherche pas à réinventer la roue, juste me servir de ce programme comme support d'apprentissage

    Rentrons maintenant dans le vif du sujet.

    En premier lieu, suite aux conseil avisés reçus auparavant, tout le programme fonctionnera en mode console. Ce n'est qu'une fois fonctionnel que je l'adapterai sous Qt afin d'en faire un programme graphique. En conséquence, le programme devra être bâti pour nécessiter le moins de modifications possible lors de son adaptation sous Qt.

    J'ai réfléchi sur papier à la conception des objets, et fait les ébauches suivantes des headers :

    - classe DirsToScan : contient les noms des dossiers à scanner et les méthodes d'ajout/suppression de dossier à la classe, ainsi que des méthodes représentant les options à choisir par l'utilisateur pour tous les dossiers.
    - classe Directory : utilisée par DirsToScan, contient le chemin absolu d'un dossier à scanner, et les options qui lui sont liées.
    - classe Scan : contient le code pour scanner les dossier Directory pointés dans une instance DirsToScan, avec des options diverses.
    - classe Profile : charge et sauve dans un fichier un profil utilisateur. Servira particulièrement dans cette ébauche console à fournir les données au programme sans intervention d'un utilisateur.

    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
    #ifndef DIRSTOSCAN_H
    #define DIRSTOSCAN_H
     
    /*
      La classe DirsToScan représente un ensemble de dossiers à scanner. Chaque
      dossier à scanner est représenté par la classe Directory. Dans la classe, les
      objets de type Directory sont pointés dans un vector.
     
      ** Méthodes et accesseurs publiques : **
     
      Les méthodes addDir() et delDir() permettent respectivement d'ajouter et de
      supprimer un dossier. La méthode addDir() autorise des paramètres de
      récursivité dans les sous-dossiers, et un paramètre de protection contre le
      déplacement ou l'effacement des fichiers contenus dans le dossier ajouté
      (ainsi que ses sous-dossiers en cas de récursivité).
     
      setRecursivity(), setDeepRecursivity() et setProtected() sont des accesseurs
      qui permettent de modifier le statut des options de récursivité et de
      protection de tous les dossiers existants et de définir une option par défaut
      pour les ajouts futurs. Par défaut, la récursivité est permise sans limite de
      niveau (m_deepRecursivity vaut 0) et le contenu des dossiers n'est pas protégé
      (l'algorithme ne conservera qu'une copie des doublons, les autres fichiers
      étant supprimés ou déplacés selon les options du scan).
     
      listing() renvoie une liste de string représentant les chemins absolus des
      dossiers à scanner (permet d'informer l'utilisateur).
    */
     
    #include <include/Directory.h>
     
    #include <string>
     
    using namespace std;
     
    class DirsToScan
    {
    public:
        DirsToScan();
        void addDir(const string &absolutPath);
        void addDir(const string &absolutPath, const bool &protectedStatus,
                    const bool &recursivity, const unsigned int &deepRecursivity);
        void delDir(const string &absolutPath);
        void setRecursivity(const bool &recursivity);
        void setDeepRecursivity(const unsigned int &deepRecursivity);
        void setProtected(const bool &protectedStatus);
        list<string> listing();
     
    private:
        vector<*Directory> m_dirsToScan;
        bool m_recursivity = true;
        unsigned int m_deepRecursivity = 0;
        bool m_protectedStatus = false;
    };
     
    #endif // DIRSTOSCAN_H
    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
    #ifndef DIRECTORY_H
    #define DIRECTORY_H
     
    /*
      La classe Directory représente un dossier à scanner.
     
      - m_absolutPath : string représentant le chemin absolu du dossier
      - 3 autres attribut privés possédant un accesseur SetAttribut() (sans le m_) :
      . bool m_recursivity : true / false : récursivité autorisée / interdite
      . unsigned int m_deepRecursivity : profondeur de la récursivité (0 = infini)
      . bool m_protectedStatus : si true, déclare le dossier comme protégé (pas
        d'effacement/déplacement de fichiers doubons dans ce dossier et ses sous-
        dossiers éventuels).
      - explore() : va explorer le dossier et ses sous-dossiers éventuels pour
        lister les fichiers et renvoyer le résultat sous forme de chemins absolus
        dans une list<string>. Cette fonction sera appelée par le constructeur et
        par setRecursivity() et setDeepRecursivity() s'ils modifient la valeur
        existante. Cette fonction prendrait tout son intérêt dans le cadre d'un
        multi-threading, permettant un pré-traitement des données au moment de la
        sélection des dossiers et avant le lancement d'un scan.
    */
     
    using namespace std;
     
    class Directory
    {
    public:
        Directory(const string &absolutPath, const bool &protectedStatus,
                  const bool &recursivity, const unsigned int &deepRecursivity);
        setRecursivity(const bool &recursivity);
        setDeepRecursivity(const unsigned int &deepRecursivity);
        setProtectedStatus(const bool &protectedStatus);
     
    private:
        list<string> explore();
        string m_absolutPath;
        bool m_recursivity;
        unsigned int m_deepRecursivity;
        bool m_protectedStatus;
    };
     
    #endif // DIRECTORY_H
    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
    #ifndef SCAN_H
    #define SCAN_H
     
    #include <include/DirsToScan.h>
     
    /*
      La classe Scan contient la procédure de scan et ses paramètres.
     
      ** Méthodes publiques : **
      - int loadProfile() : charge un profile de paramètres inscrit dans un fichier
      dont on donne le chemin absolu. Renvoie un code différent de 0 en cas
      d'erreur.
      - int exec() : lance le scan avec les paramètres en vigueur stockés dans des
      attributs privés de la classe.
      - setNomDuParametre(T &parametre) : accesseurs à définir pour la modification
      des paramètres du scan.
    */
     
    using namespace std;
     
    class Scan
    {
        public:
            Scan(DirsToScan &directories);
            int loadProfile(string &profile);
            int exec();
            void setNomDuParametre(T &parametre);
     
        private:
        /*
        paramètres à définir (certains par enumérations ?)
        - filtres d'exclusion : fichiers cachés, fichiers système (.dll) et
        extensions diverses, taille mini/maxi, etc...
        - filtres d'inclusion : par extension
        */
    };
     
    #endif // SCAN_H
    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
    #ifndef PROFILE_H
    #define PROFILE_H
     
    /*
      La classe DirsToScan représente un ensemble de dossiers à scanner. Chaque
      dossier à scanner est représenté par la classe Directory. Dans la classe, les
      objets de type Directory sont pointés dans un vector.
     
      ** Méthodes publiques : **
      - load() et save() permettent respectivement de charger et sauvegarder un
        profile dans un fichier. Le path absolu du fichier est passé en paramètre
        sous forme d'une string. Le renvoie d'un code différent de 0 signale une
        erreur.
        Un fichier XML serait adapté : à voir pour comment le manipuler...
        Contiendrait les balises <absolutPath> <protected> <recursivity>
        <deepRecursivity> pour la partie <Directory>, <protected> <recursivity>
        <deepRecursivity> pour la partie <DirsToScan>, et les paramètres de scan
        dans la partie <Scan>.
    */
     
    using namespace std;
     
    class Profile
    {
    public:
        Profile(DirsToScan &dirsToScan, Directory &directory, Scan &scan);
        int load(string &absolutPath);
        int save(string &absolutPath);
     
    private:
    };
     
    #endif // PROFILE_H
    Questions :

    1/ Cette structure des données vous parait-elle viable ? En particulier, faut ils intégrer les données des Directory directement dans DirsToScan ? C'est ce que j'aurai été tenté de faire, mais y a t'il un conteneur du style vector<typeDeDonnées1, typeDeDonnées2, typeDeDonnées3, typeDeDonnées4> qui me simplifierai les choses, à la manière d'un QAbstractItemModel de Qt ?

    2/ Quelles sont les classes permettant de naviguer dans une arborescence de dossiers et de lister des fichiers d'un répertoire ?

    3/ Pour manipuler les fichier XML (partie profile), une lib externe comme TinyXML est-elle nécessaire ? y a t'il un moyen plus simple de faire (simple fichier texte avec des mots clés à la place des balises, et on sait que aux lignes suivantes ont trouve le bloc de données que l'on cherche ?

    Merci d'avance pour votre aide et toute remarque utile sur mon code ou autre

  2. #2
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonsoir.
    Je ne vais pas t'être d'une grande aide concernant tes questions, mais j'ai quelques remarques.

    Tout d'abord : F.A.Q C++: Quand utiliser / ne pas utiliser using namespace ?

    Ensuite, tes #include <include/Directory.h> m'étonnent.
    En général, on utilise les « chevrons » pour les fichiers de bibliothèque, et les guillemets pour les fichiers du projet.
    Ceci dit, si tu indique au compilateur où chercher les fichiers et que tu es plus à l'aise comme ça...

    Pour finir, je ne suis pas sûr de l'intérêt d'utiliser des références constantes pour les types de base.
    Je me trompe peut-être, mais tu ne gagnes pas grand chose à ne pas les passer par valeur à tes fonctions.

    Sinon, j'ai quand même un avis concernant tes questions...

    2/ Un arborescence suit une structure d'arbre.
    Mais à ma connaissance, il n'y en a pas dans le standard (peut-être avec le C++11 ?).
    Ceci dit, ce n'est pas très compliqué à faire.

    Conceptuellement, il s'agit d'un ensemble de nœuds reliés entre eux.
    Un nœud a une étiquette et un ensemble de fils (on pourra utiliser une séquence (vector, list, deque)).
    Un nœud qui n'a pas de fils est une feuille.
    Un nœud qui n'a pas de père est la racine de l'arbre (il est unique).

    Concrètement, les dossiers correspondent aux nœuds, et les fichiers aux feuilles.
    Tu peux t'inspirer de ce qui est fait pour illustrer le Design Pattern « composite » dans le cours consacré aux DP.
    J'imagine que QDir doit être ressemblant également... en plus complexe...


    3/ Cette fois j'en suis sûr, le standard ne permet pas de manipuler XML.
    Il existe libxml2 (en C) et libxml++ (en C++).
    Personnellement, j'ai toujours trouvé ces deux bibliothèques installées sur mon système (Ubuntu Linux, gcc), mais ce n'est pas forcément vrai pour tous les OS et tous les compilateurs.
    Par contre, libxml++ ne semble pas gérer l'écriture d'un fichier XML.
    Ceci dit, s'il n'est pas trop complexe, cela peut toujours se faire « à la main »...

    Le format XML n'est pas le seul utilisable pour faire des fichiers de configuration/profil.
    Celui utilisé pour les fichiers *.ini n'est pas mal aussi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [Section1]
    cle1_1 = valeur1_1
    cle1_2 = valeur1_2
    ...
     
    [Section2]
    cle2_1 = valeur2_1
    ...
    Et il y en a certainement d'autres.
    Tout dépend de la complexité des informations à conserver.
    Si c'est vraiment simple, un fichier CSV (« Comma Separated Values ») peut suffire !


    Voilà.
    Je crains de ne pouvoir t'aider plus.
    Quoiqu'il en soit, bonne continuation !

  3. #3
    Membre confirmé
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Par défaut
    Bonsoir,

    Et dire que je l'avais déjà lue cette FAQ sur le namespace...

    Citation Envoyé par Steph_ng8 Voir le message
    Ensuite, tes #include <include/Directory.h> m'étonnent.
    En général, on utilise les « chevrons » pour les fichiers de bibliothèque, et les guillemets pour les fichiers du projet.
    En fait, je ne m'étais pas posé la question, j'avais sans faire attention mis le 1er chevron et c'est Code::Blocks qui m'a proposé la suite automatiquement en auto-complétion... Les guillemets et chevrons, c'est juste une convention ou ça implique d'autres choses ?
    Dans le doute, je vais repasser en guillemets.
    EDIT : en parlant des include, j'ai oublié de les mettre dans la classe profile...

    Citation Envoyé par Steph_ng8 Voir le message
    Pour finir, je ne suis pas sûr de l'intérêt d'utiliser des références constantes pour les types de base.
    Je me trompe peut-être, mais tu ne gagnes pas grand chose à ne pas les passer par valeur à tes fonctions.
    En fait, j'avais cru comprendre qu'il valait mieux passer par référence pour limiter l'utilisation de la mémoire, et du coup passer en constante toute donnée qui ne doit pas être modifiée par la fonction, par sécurité ? Cela dit, à y réfléchir, pour les types de base ça doit effectivement être de la micro-optimisation qui complique la vie pour pas grand chose...

    Citation Envoyé par Steph_ng8 Voir le message
    2/ Un arborescence suit une structure d'arbre.
    Mais à ma connaissance, il n'y en a pas dans le standard (peut-être avec le C++11 ?).
    Ceci dit, ce n'est pas très compliqué à faire.
    Ok, je vais regarder ça.
    Mais sinon, simplement pour lister le contenu d'un dossier, il y a bien une commande accessible de base ?
    EDIT : j'ai trouvé des pistes ici :
    - http://cpp.developpez.com/telecharge...us-repertoires
    - http://cpp.developpez.com/telecharge...-un-repertoire

    Citation Envoyé par Steph_ng8 Voir le message
    3/ Cette fois j'en suis sûr, le standard ne permet pas de manipuler XML.
    Je vais surement m'orienter vers le style du .ini, je voudrais que le programme final soit multi-plateforme sans me prendre la tête.
    En plus, ce format a l'avantage d'être très accessible aux modifications manuelles en éditeur de texte.

    Citation Envoyé par Steph_ng8 Voir le message
    Voilà.
    Je crains de ne pouvoir t'aider plus.
    Quoiqu'il en soit, bonne continuation !
    C'est déjà beaucoup, merci et bonne soirée (nuit) !

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par spirzouf Voir le message
    En fait, je ne m'étais pas posé la question, j'avais sans faire attention mis le 1er chevron et c'est Code::Blocks qui m'a proposé la suite automatiquement en auto-complétion... Les guillemets et chevrons, c'est juste une convention ou ça implique d'autres choses ?
    Dans le doute, je vais repasser en guillemets.
    Avec les guillemets, le chemin relatif par rapport au fichier courant.
    Avec les chevrons, le chemin est relatif par rapport à des chemins de recherches de .h que tu configures dans ton projet. Les bibliothèques standard en font obligatoirement partie.

    Citation Envoyé par spirzouf Voir le message
    En fait, j'avais cru comprendre qu'il valait mieux passer par référence pour limiter l'utilisation de la mémoire,
    C'est vrai dans la grande majorité des cas, sauf quand la taille d'un pointeur est plus grande que la taille du type en question, comme dans le cas du caractère. Mais passer un caractère par référence peut encore avoir son utilité si tu veux modifier sa valeur dans la fonction, et que tu te réserves la valeur de retour pour définir le statut de la fonction (échec, succès, etc.).

  5. #5
    Membre confirmé
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Par défaut
    merci pour ces précisions

  6. #6
    Membre confirmé
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Par défaut
    EDIT : problème de syntaxe, j'ai oublié les parenthèses à begin et end... Le message d'erreur n'aidait pas
    Bonsoir,

    J'avance un peu.
    J'ai fini un lecteur de fichier .profile qui charge les données dans mes objets.

    Là, c'est la première fois que j'en utilise et j'ai un soucis d'iterator pour parcourir un vector.

    j'ai mon vector :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<Directory> m_dirsToScan;
    voici le départ de ma boucle for :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (vector<Directory>::iterator it = m_dirsToScan.begin; it != m_dirsToScan.end; it++)
    j'obtiens le message d'erreur suivant à la compilation :
    error: conversion from ‘<unresolved overloaded function type>’ to non-scalar type ‘__gnu_cxx::__normal_iterator<Directory*, std::vector<Directory, std::allocator<Directory> > >’ requested
    error: no match for ‘operator!=’ in ‘it != ((DirsToScan*)this)->DirsToScan::m_dirsToScan.std::vector<_Tp, _Alloc>::end [with _Tp = Directory, _Alloc = std::allocator<Directory>]’
    L'iterator ne fonctionne que pour les types standard et il faut surcharger ??
    ou c'est autre chose... ?

    EDIT : problème de syntaxe, j'ai oublié les parenthèses à begin et end... Le message d'erreur n'aidait pas

Discussions similaires

  1. Aide pour réaliser un moteur de recherche en Vba Excel
    Par NEC14 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 22/01/2009, 12h12
  2. [Free Pascal] Besoin d'aide pour un programme
    Par ricomix dans le forum Free Pascal
    Réponses: 3
    Dernier message: 04/06/2006, 17h01
  3. aide pour un programme a compiler
    Par letombeur dans le forum C++
    Réponses: 8
    Dernier message: 11/01/2006, 21h53
  4. Réponses: 8
    Dernier message: 03/11/2005, 08h51
  5. [SQL] Aide pour un moteur de recherche
    Par Death83 dans le forum PHP & Base de données
    Réponses: 15
    Dernier message: 26/10/2005, 14h12

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