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 :

portée des variables et utilisation bibliotheque fstream


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 88
    Points : 64
    Points
    64
    Par défaut portée des variables et utilisation bibliotheque fstream
    Bonjour,

    j'aimerais savoir pourquoi dans un fichier operations.cpp (en dehors du fichier contenant le main) en incluant pourtant bel et bien la bibliothèque <fstream> et en voulant initialiser une variable de la sorte:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ofstream file;
    file.open("/home/D0ppelganger/hash/hash.txt" , ios::out);
    Netbeans m'indique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "unable to resolve identifier ofstream"
    Voici l'organisation du code en gros:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //main.cpp
    #include <cstdlib>
    #include <iostream>
     
    #include "operations.h"
    using namespace std;
     
    int main(int argc, char** argv) {
     
        //ecriture_fichier();
     
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //operations.h
    #ifndef OPERATIONS_H
    #define	OPERATIONS_H
     
    void ecriture_fichier();
     
    #endif	/* OPERATIONS_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
    #include <iostream> 
    #include <fstream>
    #include "operations.h" 
     
    ofstream file;
     
    using namespace std;
     
    //ici fonctions traitement fichier
    void ecriture_fichier(ofstream file){
     
    file.open("/home/D0ppelganger/hash/hash.txt" , ios::out);
     
    }
    Pourtant quand j'essaie d'utiliser une autre bibliotheque, je n'ai pas de probleme avec les types et fonctions qui sont automatiquement reconnus, mais là visiblement ce n'est pas le cas...Quelqu'un sait pourquoi?

  2. #2
    Membre habitué Avatar de Xtrem_Voyageur
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2009
    Messages : 85
    Points : 154
    Points
    154
    Par défaut
    Oui, il ne faut pas mettre la charrue avant les boeufs comme on dit.

    ofstream est un élément qui se situe dans le namespace std.
    donc soit tu fais
    soit tu places ton using namespace std; avant d'utiliser de déclarer ofstream
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    using namespace std;
    ofstream file;
    Et puis, veilles à ce que ta fonction ecriture_fichier ait le même prototype dans le fichier d'implémentation .cpp et le header .h

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 88
    Points : 64
    Points
    64
    Par défaut
    Merci pour ta réponse l'ami, effectivement ca marche beaucoup mieux comme ça.

    Pour ce qui est du prototype j'avais déjà corrigé ça dans mon code mais oui c'est une bonne remarque, merci pour ton aide et pour la rapidité de ta réponse

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Salut,
    Pour commencer, une toute petite remarque concernant l'utilisation de la directive using namespace ...

    Il faut vraiment veiller à ne l'utiliser que dans les fichier *.cpp car, autrement, elle risque de se répandre au gré des inclusions (directes et indirectes) du fichier dans lequel elle se trouve, et tu perds au final tout l'intérêt des espaces de noms

    De plus, le nom de l'espace de noms "std" est suffisamment court pour éviter d'user le clavier outre mesure et pour ne pas prendre énormément de temps à écrire...

    Autant ne pas utiliser cette directive pour cet espace de noms

    J'ai en effet tendance à conseiller généralement de n'utiliser la directive using namespace que lorsque les espaces de noms deviennent vraiment compliqués et de préférer, dans ce cas, la création d'un alias, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    using namespace premierEspaceDeNom:sousEspaceDeNoms Sub;
    /* et dans le code  */
    Sub::foo();
    /* ou */
    Sub::LeType var;
    Ensuite, il y a quelques petites remarques que je voudrais faire sur le code de manière générale:

    Un flux de type "ofstream" est, d'office, un fichier ouvert en écriture.

    Il n'est donc pas nécessaire de préciser ios::out dans ses paramètres, à moins que tu ne souhaites modifier le mode d'ouverture (et passer du mode "texte" au mode "binaire" )

    De plus, on préfère généralement utiliiser l'idiome appelé RAII (Ressource Acquisitiion Is Initialization, ou, si tu préfère en francais, l'aquisition de ressources sert d'initialisation), et donc, il est préférable d'appeler directement le constructeur adéquat pour un ofstream, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::ofstream file("/home/D0ppelganger/hash/hash.txt" ); // le fichier est automatiquement ouvert ;)
    Enfin, je serais surpris qu'une fonction proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ecriture_fichier(ofstream file)
    {
        /* du code */
    }
    compile, car cette fonction demande la copie de l'objet de type file qui lui est transmis, or, la classe ofstream n'est pas copiable.

    Tu devrais donc transmettre le fichier sous la forme d'une référence (non constante) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ecriture_fichier(ofstream & file)
    {
        /* du code */
    }
    et, comme le fichier est, a priori, déjà ouvert avant que tu ne fasses appel à cette fonction, il ne sert pas à grand chose (et il est meme sans doute dangereux ) de réouvrir le fichier

  5. #5
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Il y a deux syntaxes pour renommer un namespace ? Je ne connaissais que celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    namespace Sub = premierEspaceDeNom::sousEspaceDeNoms;

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Oui, au temps pour moi...

    Je fais tellement souvent des alias d'espaces de noms

    Et comme j'étais un peu pressé, je n'ai effectivement pas pris le temps de vérifier

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 88
    Points : 64
    Points
    64
    Par défaut
    Merci pour toutes vos explications, elles sont claires et concises, je ne pouvais pas en attendre autant

    Effectivement le ios::out ne sert a rien car par défaut il est utilisé implicitement dans la fonction open().

    Pour ce qui est du passage par référence c'est corrigé

    Pour en revenir aux namespaces du coup je devrai obligatoirement passer par un alias dans mes headers ou pas si je veux par exemple utiliser le type string pour créer un prototype de fonction retournant un objet string?

    Eclairez moi un peu plus à ce sujet, je n'ai peut être pas tout compris.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Citation Envoyé par Leaffy Voir le message
    Pour en revenir aux namespaces du coup je devrai obligatoirement passer par un alias dans mes headers ou pas si je veux par exemple utiliser le type string pour créer un prototype de fonction retournant un objet string?

    Eclairez moi un peu plus à ce sujet, je n'ai peut être pas tout compris.
    Dans les headers, tu utilises les noms pleinement qualifiés, sans utiliser la directive using namespace.

    tu déclarerais donc tes fonctions sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::string /* const & */ foo();
    class Truc
    {
        public:
            void bar(std::string const & ) /* const */
    };
    Pour les espace de noms plus complexe ( par exemple boost::program_option), tu peux éventuellement utiliser un alias de l'espace de noms sous la forme de namespace bpo = boost::program_options

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 88
    Points : 64
    Points
    64
    Par défaut
    D'accord, je prends note! Merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 17/02/2005, 10h05
  2. [FLASH MX] Portée des variables ???
    Par mic79 dans le forum Flash
    Réponses: 2
    Dernier message: 08/02/2005, 11h21
  3. Portée des variables vbscript vers ASP
    Par Immobilis dans le forum ASP
    Réponses: 3
    Dernier message: 03/11/2004, 11h14
  4. [XSL]Problème de portée des variables
    Par djulesp dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 17/09/2004, 11h34
  5. [Portée] portée des variables
    Par parksto dans le forum Langage
    Réponses: 7
    Dernier message: 09/05/2004, 22h05

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