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++

  1. #1
    Membre régulier
    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
    Points : 97
    Points
    97
    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 éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    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 régulier
    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
    Points : 97
    Points
    97
    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 émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 704
    Points
    2 704
    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 régulier
    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
    Points : 97
    Points
    97
    Par défaut
    merci pour ces précisions

  6. #6
    Membre régulier
    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
    Points : 97
    Points
    97
    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

  7. #7
    Membre régulier
    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
    Points : 97
    Points
    97
    Par défaut Problème pour récupérer un chemin complet de dossier
    Bonjour,

    En cherchant en C++ un équivalent au QDir de Qt4, je n'ai trouvé qu'une solution nécessitant des librairies de C. Peut on faire un équivalent en C++ "pur" qui m'éviterait de charger des headers de C et d'utiliser des conversions de string vers char ?

    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
    /*
    Affichage des fichiers et dossiers contenus dans un répertoire.
    Source : http://c.developpez.com/faq/?page=fichiers#FICHIERS_dir_list
    */
     
    #include <cstdio>
    #include <dirent.h> // dirent : DIRectory ENTity
    #include <string>
     
    void explore(std::string cheminAbsolu)
    {
        DIR * dossier = opendir(cheminAbsolu.c_str());
     
        if (dossier != NULL)
        {
            struct dirent * entite; // entité de classe DIRectory ENTity
            while ((entite = readdir(dossier)) != NULL)
            {
                // vérifie si l'entité est un dossier
                std::string nomDossier = entite->d_name;
                if (nomDossier !="." && nomDossier !="..")
                {
                    if (entite->d_type == DT_DIR)
                    {
                        printf("Dossier : \t%s/%s\n",cheminAbsolu.c_str(),entite->d_name);
                        // récursivité dans le sous dossier
                        std::string CheminAbsoluSousDossier = cheminAbsolu + "/" + nomDossier;
                        explore(CheminAbsoluSousDossier);
                    }
                    else
                    {
                        printf("%s/%s\n",cheminAbsolu.c_str(),entite->d_name);
                    }
                }
            }
            closedir(dossier);
        }
    }
     
    int main(void)
    {
        std::string cheminAbsolu ="/home/cyril/test";
     
        explore(cheminAbsolu);
     
        return 0;
    }

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par spirzouf Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (vector<Directory>::iterator it = m_dirsToScan.begin; it != m_dirsToScan.end; it++)
    Pour appeler la fonction begin, il faut mettre begin(). Idem pour end.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #9
    Membre régulier
    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
    Points : 97
    Points
    97
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Pour appeler la fonction begin, il faut mettre begin(). Idem pour end.
    J'aurais du mettre mon EDIT en haut de mon post au lieu d'en bas... j'ai auto-résolu ce petit problème le jour même

    C'est mon dernier post où je bloque Aurais tu une réponse à ce sujet ?

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    boost.filesystem. Mais tu auras alors besoin de boost.

    Il n'y a rien en standard pour faire ça en C++ (ni en C d'ailleurs : les fonctions que tu utilises sont spécifiques à un OS).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre régulier
    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
    Points : 97
    Points
    97
    Par défaut
    Je m'en doutais un peu, n'ayant effectivement rien trouvé autre que boost dans mes recherches. J'espérais au moins un équivalent de dirent.h adapté au C++ et qui prendrait les string, mais bon...

    Je verrais plus tard pour installer boost et réécrire ma fonction avec.

    Merci pour l'info.

  12. #12
    Membre régulier
    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
    Points : 97
    Points
    97
    Par défaut Ouverture en lecture de fichier vide
    Bonjour,

    J'ai un petit problème qui m'a permis de découvrir le débogage dans code::blocks

    J'ai une fonction qui me renvoie la taille d'un fichier. Je me suis rendu compte que cette fonction bloque lors de l'initialisation du flux si on a en paramètre le chemin d'un fichier existant mais vide. Le programme ne plante pas mais semble rester "coincé" sur cette instruction : en mode débogage, je n'arrive pas à passer à l'instruction suivante, et aucun message d'erreur n'apparait.

    Comment détecter l'existence d'un fichier vide sans bloquer le programme ?

    Voici le code de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    unsigned long long getSize(string filePath)
    {
        // ouverture du fichier
        ifstream fichier(filePath.c_str()); // *** ligne qui bloque si fichier vide ***
        // aller en fin de fichier
        fichier.seekg( 0 , ios_base::end );
        // position de fin de fichier = taille du fichier
        unsigned long long size = fichier.tellg();
        // fermeture du fichier
        fichier.close();
        return size;
    }

  13. #13
    Membre régulier
    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
    Points : 97
    Points
    97
    Par défaut
    Suite à mon poste précédent, j'ai fait d'autres tests et il se trouve que 2 autres fichiers vides sont parfaitement lus.

    Le seul fichier qui pose problème s'appelle .zoteroIntegrationPipe
    c'est un fichier de type "tube" qui affiche 0 octets dans les propriétés issues de dolphin (mon explorateur de fichier), contrairement aux 2 autres qui sont indiqués comme étant des "fichier vide".
    De la même façon, ce fichier n'est pas copiable en passant par mon explorateur de fichier, alors que les 2 autres le sont.
    J'ai bien les droits en lecture et écriture dessus.

    Comment se fait il qu'un fichier puisse bloquer une initialisation d'un objet ifstream, sans renvoyer de message d'erreur ?

  14. #14
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Renseigne-toi sur les tubes Unix, ce sont des 'fichiers' extrêmement particuliers (en termes Unix ce ne sont pas des fichiers réguliers) et il n'y a rien d'étonnant à ce qu'ils bloquent ta commande de lecture.

  15. #15
    Membre régulier
    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
    Points : 97
    Points
    97
    Par défaut
    Merci pour ce renseignement.

    Par contre, comment faire pour détecter qu'il s'agit d'un tel fichier et donc ne pas tenter de créer un flux de lui vers le programme avec ifstream ?
    J'ai trouvé ce document, mais je ne comprend pas certain de comprendre comment obtenir la structure contenant le st_mode pour ne tenter d'ouvrir que les S_IFREG (fichiers "régulier").

    Il faudrait faire un truc dans ce genre ci ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <sys/mode.h>
    #include <sys/stat.h>
    stat("/home/user/monFichier", struct stat *statsDeMonFichier);
    if (statsDeMonFichier->st_mode == S_IFREG)
    {
        // lancer getSize()
    }
    Ma fonction getSize devient même inutile dans ce cas car la structure stat permet aussi d'avoir la taille du fichier apparemment (st_size) ?

    C'est quand même pas facile de faire certains trucs "simples" (faire une arborescence de fichiers, obtenir leur taille) en C++ ??

    Dernière question : sous windows, y a t'il aussi des fichiers spéciaux qui peuvent aussi faire planter ifstream ?

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