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 :

question curiosité ofstream ifstream


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut question curiosité ofstream ifstream
    Bonjour,

    Comme je le dis en titre, ce n'est qu'une question de curiosité dont la réponse ne me servira que pour ma culture perso, à moins qu'elle ne soit positive (dans ce cas là, j'appliquerai la réponse quand j'aurai le temps)

    Dans mes programmes, en général j'ai un tas de fichiers que je crée ou lis et j'ai donc dans mon main, tout un tas d'ouverture de fichiers, ce qui prend de la place et gêne la lisibilité de mon programme (enfin je trouve) car à chaque fois j'écris tout ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      ifstream Fdata;
      Fdata.open("hd180642.dat");
      if (!Fdata)
        {
          cout<<"Error opening Fdata file"<<endl;
          return 1;
        }
    Et 7 lignes multipliées par x fichiers, ça fait beaucoup.

    Alors, je me pose une question, est ce qu'il est possible de sortir de mon programme principal toutes ces ouvertures de fichiers pour les mettre dans un autre fichier que je pourrai appeler via #include, un peu comme on fait avec les définitions de fonctions ?
    J'aurai tendence à penser que non mais comme j'ai peu d'expérience et donc peu de connaissances, je préfère vous le demander...

    Et si oui, cela ne gène pas que les fermetures des fichiers restent dans mon programme principal ?

    voilà voilà


  2. #2
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par hibiscuit Voir le message
    Dans mes programmes, en général j'ai un tas de fichiers que je crée ou lis et j'ai donc dans mon main, tout un tas d'ouverture de fichiers, ce qui prend de la place et gêne la lisibilité de mon programme (enfin je trouve) car à chaque fois j'écris tout ça :
    J'ai envie de dire que si t'as tout un tas d'ouverture de fichier dans ton main, tu as effectivement un problème... de conception a priori.
    En effet, si tu répètes n fois la même action, alors il y a de forte chance qu'une abstraction t'aie échappée. -> construction d'une classe.

    Dans un main, tu ne devrais pas avoir grand chose. L'idéal étant un programme où il n'y a pas vraiment de programme principal (enfin si quand même, y'a forcément un main mais c'est pas ce que je veux dire). Le programme devrait être composé de modules au maximum indépendants, chacun réalisant un petit truc bien précis...
    Ton main devrait alors être très court.

    Personnellement, le main du projet que je viens de terminer (plus de 30 000 lignes de code) est le plus petit de tous les fichiers de mon projet.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    La premier principe qu'il faut apprendre et veiller à respecter avant tout, lorsque l'on apprend à programmer tient en deux phrases:
    • Déléguer tout ce qui peut être délégué
    • une fonction n'a qu'une responsabilité (ou un nombre restreint de responsabilités)

    Et cela, même si on travaille en procédural (en "non orienté objet")

    Ainsi, main qui va quand même mettre toute la machine en branle, devrait dans bien des cas pour ainsi dire se contenter d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main()
    {
        Initialisation();
        Travail();
        Liberation();
        return 0;
    }
    La fonction Initialisation aura pour but de s'assurer que l'on dispose de tout ce qu'il faut, la fonction Travail fournira le plus souvent une boucle du genre de "tant qu'on ne m'a pas dit d'arrêter, je continue" et la fonction Libération s'occupera de veiller à ce que toutes les ressources allouées pour le travail ont été correctement libérées.

    Dans ton cas, la fonction d'initialisation devra sans doute se charger de la création d'une liste de fichiers, éventuellement, avec certaines informations concernant le type de données que chaque fichier est sensé contenir.

    On pourrait estimer comme probable (à adapter à ta situation propre) qu'il existe un fichier qui reprend l'ensemble de ces informations sous une forme proche, par exemple de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* exemple de fichier "liste.txt*/
        <nom>         <type de donnee>
    monfichier.dat          data1
    fichier2.dat            data2
    fichier3.dat            data3
    ...
    (où le type de données serait, pourquoi pas, une simple énumération permettant de savoir ce qu'il en est )

    Tu aurais donc une structure du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct FileInfo
    {
        enum type
        {
            data1,
            data2,
            data3,
            data4/*,...*/
        };
        std::string filename,
        type t;
    };
    Et la fonction Initialisation deviendrait alors
    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
    std::vector<FileInfo> Initialisation()
    {
        std::vector<FileInfo> ret;
        std::ifstream ifs("liste.txt");
        std::string str
        while( std::getline(ifs,str))
        {
            std::stringstream ss;
            ss<< str;
            TypeInfo temp;
            ss>>temp.filename;
            ss>>temp.t;
            ret.push_back(temp);
        }
        return ret;
    }
    La fonction Travail() deviendrait quelque chose prenant la forme de
    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
    Travail(const std::vector<TypeInfo>& tab)
    {
        for(size_t i=0;i<tab.size();i++)
        {
            switch(tab[i].t)
            {
                case data1:
                    ReadFileDataType1(tab[i].name);
                    break;
                case data2:
                    ReadFileDataType2(tab[i].name);
                    break;
                case data3:
                    ReadFileDataType3(tab[i].name);
                    break;
                case data4:
                    ReadFileDataType4(tab[i].name);
                    break;
              /* case ... */
            }
        }
    }
    (ou les fonctions ReadFileDataTypeN seraient à chaque fois une fonction prenant en charge un type particulier de fichier)

    et donc, main deviendrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main()
    {
        std::vector<FileInfo> todo=Initialisation();
        Travail(todo);
        /* ici, pas besoin de "nettoyage"... enfin... selon les cas ;-) */
        return 0;
    }
    Evidemment, le fait de passer en version orientée objet peut permettre quelques trucs sympa... et je n'ai rien mis concernant la gestion éventuelle d'erreur (un fichier qui n'existe pas, par exemple).

    Mais cette manière de travailler te permettra de garder en permanence des fonctions les plus petites possibles, et donc de gagner énormément en lisibilité
    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
    Mars 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut
    Le travail risque d'être plus compliqué que je ne pensais
    Merci pour vos conseils. Je savais déjà que le main doit être tout petit par rapport aux différents modules du programme mais c'est vrai que pour moi qui débute (toute seule en plus ), j'ai quelques difficultés à le conserver petit...

    J'avais déjà commencé à alléger mon main en écrivant un tas de fonctions que je ne vais plus tarder à mettre dans plusieurs fichiers .cpp (maintenant qu'elles sont écrites et qu'elles fonctionnent)
    Il est vrai que pour le moment, je ne suis pas au top niveau lisibilité du main, mais je m'améliore et j'espère que je vais continuer à m'améliorer (il va bien falloir, car la programmation sera presque la seule chose que j'aurai apprise pendant ma thèse et du point de vue des employeurs, ce sera le seul truc potable que je pourrai mettre en avant.... vive les études dans des domaines pointus qui n'ont aucune application dans la vie de tous les jours...... .... il me reste deux ans.... viiiite !! )
    Bref, je m'égare.....

    J'ai d'ailleurs une nouvelle question : J'ai tout un tas de variables, paramètres, compteurs, tableaux, etc. à déclarer pour pouvoir utiliser mes fonctions. Pour le moment, elles sont toutes dans mon main... naturellement......
    Est-ce qu'il est possible de les mettre (en partie ?) dans un fichier .h ? J'ai aperçu cette pratique en fouillant le net.
    J'ai fait un essai basique en incluant dans mon fichier.cpp un fichier.h dans lequel j'avais juste écrit et dans mon main, en gros, il n'y avait que ça :
    Ca avait l'air de marcher mais est-ce que c'est "propre" comme façon de faire ?
    Désolée, je suis un peu paumée...

    Et sinon, vous savez où je peux trouver des sources de programmes en C++ (pas trop compliqués non plus) pour m'inspirer de la structure du programme ?


    Est-ce que vous pensez que je devrais renommer l'intitulé de mon premier message comme je suis en train de m'éloigner du sujet principal ?


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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    De manière générale, il vaut mieux éviter ce que l'on appelle les "variables globales", pour toute une série de raisons que l'on peut t'expliquer si tu en fait la demande (sinon, tu peux te contenter de savoir que c'est à éviter )

    Or, il faut savoir que, si tu déclare une variable en dehors de toutes fonction, tu en fais, "de facto" une variable qui sera globale pour tous les endroits où le fichier d'en-tête (*.h) est inclus, et cela comprend le phénomène d'inclusion en cascade (c.h qui inclus b.h qui inclus a.h fait si une variable globale est déclarée dans a.h, elle sera déclarée partout où tu aura une inclusion de c.h)

    Il faut savoir que l'idéal reste toujours de ne déclarer une variable (quelle qu'elle soit) que quand tu en a réellement besoin, et que, si tu travailles dans une optique orientée objet, l'idéal est même de mettre en oeuvre le paradigme que l'on nomme RAII(Ressource Aquisition Is Initialisation), qui implique qu'il faille attendre, avant de déclarer une variable d'un type personnalisé, de disposer de l'ensemble des informations permettant de l'initialiser correctement

    Essaie aussi de créer des structures correctes en regroupant les valeurs qui sont destinées à fonctionner en même temps (une personne, c'est un nom, un prénom et un age, et le tout est étroitement lié...Même si les types de données utilisés pour représenter chacune de ces informations est différent )

    *Envisage* peut être la programmation orientée objet, car, après tout, C++ est un langage ayant une excellente capacité Orientée Objet. Cela te permettra d'aller d'autant plus loin dans le principe énoncé plus haut

    Juste à titre informatif, quelles études as-tu entreprises, où cela, et sont-elles finies
    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

  6. #6
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Je plussoie complètement Koala...
    Mais je mettrai quand même un bémol. C'est à toi de voir si tu veux t'améliorer un peu dans la programmation, ou bien beaucoup. Donc en gros, est-ce simplement un outil passager, ou bien est-ce une composante principale dans ton métier.
    Pour ma part, étant dans le traitement du signal, c'est indispensable de "bien" programmer (RAII, orienté objet, etc...). A toi de voir si c'est ton cas aussi.
    Car tout ce que vient de t'expliquer Koala demande un peu (beaucoup) de temps de pratique passé à ça. Dans le cadre d'une thèse, tu ne peux peut-être pas te permettre de perdre trop de temps en programmation "pure". Un code approximatif suffirait pour une analyse physique s'il n'est pas destiné à être repris. (ça me fait mal de dire ça mais c'est la triste vérité).

    En tout cas, si tu souhaites te mettre sérieusement à la programmation, tu trouveras tout ce que tu as besoin dans les forums et dans la FAQ !

    Bonne continuation

Discussions similaires

  1. Réponses: 20
    Dernier message: 11/12/2007, 17h34
  2. Question de curiosité sur du code
    Par defluc dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 08/09/2007, 16h12
  3. Réponses: 13
    Dernier message: 27/02/2007, 11h31
  4. utiliser ifstream et ofstream successivement
    Par pit9.76 dans le forum SL & STL
    Réponses: 2
    Dernier message: 01/04/2006, 17h48
  5. [flux] héritage combiné d'ifstream et d'ofstream
    Par suizokukan dans le forum SL & STL
    Réponses: 5
    Dernier message: 08/11/2004, 17h09

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