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 :

flux de saisie : fichier ou cin au choix


Sujet :

C++

  1. #1
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut flux de saisie : fichier ou cin au choix
    Je souhaite créer un interpréteur, capable de lire cin ou un fichier, selon un argument de ligne de commande.

    Supposons le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main(int argc, char*[] argv) {
    //validation des arguments 
     
    //sélection du flux
    istream input = (argc == 1 ? cin : ifstream(argv[1]));
     
    int x, y;
    input >> x >> y;
    cout << x << " : "<< y << endl;
    }
    Sauf que cela pose plusieurs problèmes: le istream ne devrait pas être copié, et il doit être modifiable.
    Cela correspond assez bien à une référence non constante.

    Certes, mais comment l'initialiser, sans créer un ifstream si j'utilise cin?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  2. #2
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Salut,

    je n'aime pas manipuler les stream, donc perso je ferais une petite hiérarchie de classe type template method, avec une fonction membre read(). Après je ne sais pas si c'est la meilleure solution, ni si elle est adaptée à tes besoins concrets.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  3. #3
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    istream input = (argc == 1 ? istream(cin.rdbuf()) : ifstream(argv[1]));
    Par contre attention le buffer sera partagé entre input et cin. Tu peux aussi mettre un autre buffer (toujours avec rdbuf) sur cin en attendant et mettre un assert/exception pour être sur que tu t'en serviras pas entre temps... Tu peux aussi faire l'inverse et mettre le buffer de ton fichier dans cin... attention à la durée de vie par contre.

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    C'est ce problème de durée de vie qui m'embête.

    Un peu plus de détail:
    Je vais écrire une fonction void fonction(istream &);, et lui donner soit cin, soit un ifstream créé si nécessaire.


    Je me retrouve avec une référence non-constante vers une ressource chère, et je n'arrive pas à initialiser conditionnellement.
    C'est ce problème que j'aimerai résoudre.

    Est-ce qu'une solution à base de wrapper est envisageable?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void fonction(std::istream &);
     
    void fonction_sur_cin() {
        fonction(std::cin);
    }
     
    void fonction_sur_fichier(const char* chemin) {
        std::ifstream fichier(chemin);
        fonction(file);
    }


    Mon objectif réel étant cette fonction, cœur d'une future bibliothèque, pas le main qui construit simplement un programme jouet autour de la fonction.

    Mon problème est assez théorique, parce qu'ici, il disparait car je peux dupliquer le traitement qui suit.
    Comme j'autorise plusieurs fichiers d'entrée, j'obtiens le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void fonction(istream &);
     
    int main(int argc, char*[] argv) {
        if (argc==1) {
            fonction(cin);
        } else {
            for (int i = 1; i< argc; ++i) {
                //j'omets la vérification d'existence du fichier pour plus de clarté
                ifstream stream(argv[i]);
                fonction(stream);
            }
        }
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

Discussions similaires

  1. lecture fichier avec cin
    Par InfoGitan dans le forum Débuter
    Réponses: 23
    Dernier message: 05/02/2009, 15h16
  2. Saisie dans un DBEdit et choix automatique
    Par jojo86 dans le forum Bases de données
    Réponses: 2
    Dernier message: 22/02/2008, 14h46
  3. VS 2005 Envoyer le flux d'un fichier
    Par cyrilc dans le forum ASP.NET
    Réponses: 1
    Dernier message: 28/09/2007, 16h39
  4. Réponses: 1
    Dernier message: 02/01/2007, 19h55
  5. Réponses: 5
    Dernier message: 20/03/2006, 12h35

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