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 :

detection de la fin de fichier


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 1
    Par défaut detection de la fin de fichier
    Salut,

    En fait je dois faire un programme qui lit un fichier d'entiers (la premiere ligne est une ligne de caractere) et qui recopie certaines de ces valeurs dans un autre fichier.
    Mon probleme est la boucle while qui va lire toutes les lignes du fichier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if (fichier)
    	{		
    		char blabla[5],tata[5],sat[5],xas[5],yar[5],bar[5],qar[5],par[5];
    		fichier>>blabla>>tata>>sat>>xas>>yar>>bar>>qar>>par;
    		int index ,al ,type,hdm,ac,grad_al,grad_ac,flux;	
    		while(!feof);
    		{				
    			fichier >> index >> al >> type >> hdm >> ac >> grad_al >> grad_ac >> flux;			
    			cout<<al<<endl;
    			fprintf(newfile,"circle( %d ,%d ,30 ) # color= blue \n",al,ac);	
    		}
    		cout<<"c bon"<<endl;
    		fichier.close(); 
    	}
    merci....

  2. #2
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 545
    Par défaut
    Bonjour,

    lorsque vous donnez du code sur plusieurs lignes merci de mettre le mettre entre des balises CODE

    Citation Envoyé par astro94 Voir le message
    while(!feof);
    il y a là 2 erreurs
    • le ';' fait que la boucle à un corps vide (et qui n'est donc pas le bloc {} qui suit)
    • feof étant la fonction C, elle n'a aucune chance d'être nulle


    bizarre aussi ce mélange entre les iostream et stdio
    Bruno Pagès, auteur de Bouml (freeware), mes tutoriels sur DVP (vieux, non à jour )

    N'oubliez pas de consulter les FAQ UML et les cours et tutoriels UML

  3. #3
    la_tupac
    Invité(e)
    Par défaut
    Non c'est pas bizard c'est classique du débutant en C et qui migre doucement vers le ++. Mais Bruno a raison stdio est du C et le plus simple c'est d'utiliser fstream (C++)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <fstream>
     
    ofstream MonFichier;
    MonFichier.open("fichier.txt");
    MonFichier << "le nombre est" << nombre << endl;
    MonFichier.close();
    La ref cplusplus : http://www.cplusplus.com/reference/iostream/ofstream/

    courage !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut, et bienvenue sur le forum
    Citation Envoyé par la_tupac Voir le message
    Non c'est pas bizard c'est classique du débutant en C et qui migre doucement vers le ++. Mais Bruno a raison stdio est du C et le plus simple c'est d'utiliser fstream (C++)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <fstream>
     
    ofstream MonFichier;
    MonFichier.open("fichier.txt");
    MonFichier << "le nombre est" << nombre << endl;
    MonFichier.close();
    La ref cplusplus : http://www.cplusplus.com/reference/iostream/ofstream/

    courage !
    A vrai dire, il y a même encore plus simple: profiter du RAII (Ressource Acquisition Is Initialization) et de son effet contraire...

    En effet, l'un des constructeurs de *fstream admet comme premier paramètre, le nom du fichier à ouvrir, et, lorsqu'une instance de *fstream est détruite, le fichier est automatiquement fermé.
    Nous pourrions donc parfaitement envisager un code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void foo()
    {
        std::ifstream ifs("fichier_d_entree.txt"); //automatiquement ouvert
        /*... */
    } // ifs est détruit (parce que l'on sort de la portée dans laquelle il 
      // est déclaré) et donc fermé :D
    De même, il existe un opérateur de conversion de *fstream en booléen, qui renvoie vrai tant que le flux est dans un état valide (et donc tant que l'on peut tenter une lecture suivante)

    Une boucle de lecture classique dans un fichier pourrait donc prendre une forme "toute simple" proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void foo()
    {
        std::ifstream ifs("fichier_d_entree.txt"); //automatiquement ouvert
        while(ifs)
        {
            /*effectuer la lecture ici */
        }
    } // ifs est détruit (parce que l'on sort de la portée dans laquelle il 
      // est déclaré) et donc fermé :D
    Par contre (je reviens sur le code original de astro94), il est toujours préférable d'éviter le recours aux chaines de caractères "C style" (et, de manière générale, à toute possibilité issue du C) à chaque fois que l'on peut, au profit de l'utilisation de la classe string, disponible dans l'espace de noms std (ou de toute possibilité propre du C++).

    Les chaines de caractères C style présentent en effet une multitude de problèmes, allant du risque d'oublier d'ajouter le '\0' en fin de chaine aux problèmes de tailles et ou de libération de la mémoire, et les possibilités propres au C++ sont généralement plus sécurisantes que leur équivalent en C.

    De plus, même si ce n'est qu'un avis personnel, je préfère éviter de déclarer plus d'une variable par ligne...

    Cela ne change rien, au niveau de l'exécutable, d'utiliser cinq lignes pour déclarer autant de variables, mais cela facilite énormément la relecture par la suite, en évitant de faire passer une (ou plusieurs) déclarations "au bleu".

    Le code original serait donc avantageusement modifié en quelque chose proche 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    void function(std::string const  & filename)
    {
        std::ifstream fichier(filename.c_str()); //ouverture du fichier de lecture
        std::ofstream newfile("sortie.txt")
        if (fichier)
        {		
            std::string blabla;
            std::string tata;
            std::string sat;
            std::string xas;
            std::string yar;
            std::string bar;
            std::string qar;
            std::string par;
            fichier >> blabla >> tata
                    >> sat >> xas
                    >> yar >> bar
                    >> qar >> par;
            int index;
            int al;
            int type;
            int hdm;
            int ac;
            int grad_al;
            int grad_ac;
            int flux;	
            while(fichier);
            {				
                fichier >> index >> al 
                        >> type >> hdm 
                        >> ac >> grad_al
                        >> grad_ac >> flux;			
                 std::cout <<al << std::endl;
                 newfile << "circle("<<al<<","<<ac
                         <<",30) # color: blue"<<std::endl;
            }
            cout<<"c bon"<<endl;
    }
    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

  5. #5
    la_tupac
    Invité(e)
    Par défaut
    Merci mais je ne suis pas nouveau (même si je ne suis pas très actif )
    Très bon post au passage. Mais ce que tu veux dire c'est qu'en ouvrant le fichier dans le constructeur, on a plus besoin de le close() ? Parce-que j'ai déjà rencontré des soucis de ofstream non crée, simplement car je n'avais pas géré le close(). En tout cas si la réponse est oui, il faudra s'assurer que le destructeur est bien appelé. C'est pas forcément évident dans le cas de classes dérivées ...

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    On n'a déjà pas besoin de close de manière générale, à moins que l'on ne veuille fermer explicitement le fichier alors que l'instance du flux existe encore.

    Si tu crées une classe ou une structure dont un des membre est un flux de fichier, cela implique, effectivement, que le fichier ne sera fermé que... lorsque l'instance de la classe ou la structure en question sera détruite (et donc que le flux fichier membre sera lui aussi automatiquement détruit).

    Tu pourrais donc avoir des problèmes avec des classes proches 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
    class Reader
    {
        public:
            Reader(std::string const & filename_):ifs(filename_.c_str()){}
            void read(/*...*/);
        private:
            std::ifstream ifs;
    };
    class Writer
    {
        public:
            Writer(std::string const & filename_):ofs(filename_.c_str()){}
            void write(/*...*/);
        private:
            std::ofstream ofs;
    };
    si tu essaye de créer une instance de chaque classe avec le même nom de fichier dans une même portée, soit quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        Reader rd("monfichier.txt"); // crac : le fichier est ouvert une première fois
        Writer wt("monfichier.txt"); // boum : le fichier ne peut être ouvert une
                                     // deuxième fois
        /*...*/
        return 0;
    }
    Et ce sera encore plus criant si les classes entrent dans une hiérarchie d'héritage, car les instances seront classiquement créées de manière dynamique, et nécessiteront donc une destruction explicite (avec delete).

    Mais il faut aussi comprendre que cela peut demander énormément de ressource de maintenir un flux ouvert, et donc qu'il est préférable que les instances de flux n'existent, quoi qu'il en soit, que le moins longtemps possible.

    C'est la raison pour laquelle l'idéal reste de ne maintenir dans ces classes que... le nom du fichier, et de ne créer le flux que... dans la fonction qui en a besoin:
    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
    class Reader
    {
        public:
            Reader(std::string const & filename_):filename_(filename_){}
            void read(/*...*/) 
            {
                std::ifstream ifs(filename_.c_str());
                /* processus de lecture */
            } // le fichier sera bien fermé en fin de fonction :D
        private:
            std::string filename_;
    };
    class Writer
    {
        public:
            Writer(std::string const & filename):filename_(filename){}
            void write(/*...*/) const
            {
                std::ofstream ofs(filename_.c_str());
                /* processus d'écriture */
            }// le fichier sera bien fermé en fin de fonction :D
        private:
            std::string filename_;
    };
    et tu n'aura donc plus le moindre problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        Reader rd("monfichier.txt"); // OK : aucun fichier n'est ouvert
        Writer wt("monfichier.txt"); // idem
        rd.read(/*...*/); /* aucun problème: le fichier est ouvert et refermé 
                            * de manière automatique
                            */
        wt.write(/*...*/); // idem
     
    }
    J'en profite pour rappeler qu'une saine pratique consiste à ne demander des ressources que lorsque l'on en a réellement besoin, hein

    PS :le bienvenue sur le forum s'adressait en réalité à astro94
    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

Discussions similaires

  1. Apposer le caractere de fin de fichier.
    Par moldavi dans le forum Windows
    Réponses: 2
    Dernier message: 17/02/2005, 14h20
  2. "error : fin de fichier inattendue" en C++
    Par mateo.14 dans le forum MFC
    Réponses: 9
    Dernier message: 28/01/2005, 09h30
  3. Réponses: 4
    Dernier message: 07/12/2004, 08h11
  4. [CLOB] Détection caractère de fin
    Par SheikYerbouti dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 26/08/2004, 17h15
  5. Lire de la 2eme ligne à la fin du fichier
    Par iamspacy dans le forum Linux
    Réponses: 3
    Dernier message: 03/05/2004, 13h23

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