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 :

ifstream, ofstream, boucle


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut ifstream, ofstream, boucle
    Bonjour à tous !
    Voila, je débute en C ++, et j'ai un fichier texte se présentant sous la forme

    triangle 1
    valeur 1 valeur 2 valeur 3
    valeur 4 valeur 5 valeur 6
    triangle 2
    valeur 7 valeur 8 valeur 9
    valeur 10 valeur 11 valeur 12
    triangle 3
    valeur 13 ....etc

    Bref je pense que vous avez compris, et cela fait 20 000 lignes en tout lol.

    J'aimerai en fait créer un autre fichier texte reprenant exactement celui la, mais avec UN SEUL triangle c'est a dire :

    triangle 1
    valeur 1 valeur 2 valeur 3
    valeur 4 valeur 5 valeur 6
    valeur 7 valeur 8 valeur 9
    valeur 10 etc...

    Je pense faire un ifstream/ofstream pour scanner et écrire.

    Mais ce qui m'ennui c'est qu'on ne peut pas "enlever" une ligne de texte dans une boucle ...

    Qu'en pensez-vous ? Merci d'avance pour votre aide,

    Cordialement,

    reptilia1251

  2. #2
    Invité
    Invité(e)
    Par défaut
    Si je comprends bien, tu veux lire ton fichier de départ, et le recopier en sautant une ligne sur trois (sauf la première), tu vas donc avoir quelque chose comme


    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
     
    ifstream fin("tonfichier.txt");
    ofstream fout("leresultat.txt");
    string s;
    // le compteur de lignes
    int i=0;
    // lit la première ligne
    getline(fin,s);
    // sur tout le fichier
    while(!fin.eof()) {
      // i%3==0 : i est multiple de trois
      if(i%3!=0 || i==0) {
        // ecrit ta ligne
        fout<<s<<'\n';
      }
      i++;
      // lit la ligne suivante
      getline(fin,s); 
    }
    // ces fermetures ne sont pas nécessaires, 
    // mais elles ne peuvent pas nuire non plus
    fin.close();
    fout.close();
    Francois

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Merci bien fcharton !
    J'ai eu qq problèmes à la compilation, mais ça marche à la fin !

    Tu avais mis (!fin.eof()) mais apparemment, il y a () en trop !
    Et le compilateur n'aimait pas trop fin.close(); fout.close(); Mais tu as justement précisé que ce n'était pas obligatoire !

    Merci encore (je teste ça demain sur le grand fichier, j'espère qu'il n'y aura pas de problème),

    A +

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par reptilia1251 Voir le message
    Tu avais mis (!fin.eof()) mais apparemment, il y a () en trop !
    C'est étrange, eof() est une fonction standard de basic_ios, je crois...

    Citation Envoyé par reptilia1251 Voir le message
    Et le compilateur n'aimait pas trop fin.close(); fout.close(); Mais tu as justement précisé que ce n'était pas obligatoire !
    Ca aussi... il doit te manquer quelque chose quelque part...

    Il te disait quoi, ton compilateur?

    Francois

  5. #5
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Soit dit en passant on utilise pas eof() pour tester la fin d'un fichier dans une condition de sortie de boucle.
    On préférera utiliser getline() pour plus de détail sur le pourquoi de la chose voir la faq.

    Mais ça n'empêche que t'as un problème c'est bien eof() et non eof.

    Pour les appelles à close() oublie les ils sont dans ce cas inutile. (d'ailleurs fcharton la fait remarqué... x) )
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  6. #6
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Edit : Goten m'a doublé.
    On peut simplifier un peu la logique de lecture du fichier, en utilisant le code de la faq :
    Citation Envoyé par FAQ
    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
     
    #include <string>
    #include <fstream>
    #include <iostream>
     
    int main()
    {
        // le constructeur de ifstream permet d'ouvrir un fichier en lecture
        std::ifstream fichier( "fichier.txt" );
     
        if ( fichier ) // ce test échoue si le fichier n'est pas ouvert
        {
            std::string ligne; // variable contenant chaque ligne lue
     
            // cette boucle s'arrête dès qu'une erreur de lecture survient
            while ( std::getline( fichier, ligne ) )
            {
                // afficher la ligne à l'écran
                std::cout << ligne << std::endl;
            }
        }
    }
    Pour les erreurs de compilations, peut-être manque-il des includes ?
    Ici, il faut <iostream> <fstream> et <string>.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Goten Voir le message
    Pour les appelles à close() oublie les ils sont dans ce cas inutile. (d'ailleurs fcharton la fait remarqué... x) )
    Perso, j'ai tendance à toujours écrire mes close(), et souvent même à leur ajouter des clear()... Cela garantit

    1- que le fichier est fermé dès qu'on n'en a plus besoin (généralement ce n'est pas grave, mais ca peut avoir son importance)
    2- que l'on peut éventuellement réutiliser le même ifstream sur un autre fichier (le genre de chose qu'on fait dans l'urgence, quand on découvre qu'il nous manque une donnée dans un second fichier, et qui amène bien des déconvenues si les bits d'erreur du fichier précédent sont restés en place)

    Cela indique également à un relecteur quand on lit un fichier, et quand on en a fini... Dans des processus de traitement un peu complexes, c'est généralement très utile (dans ce domaine, je conseillerais également l'écriture explicite des open(), plutôt que via l'instanciation).


    Pour eof(), je suis bien sur d'accord, mais il me semble qu'il faudrait alors ajouter (à la sortie de la boucle) un test minimal de sortie, pour savoir si la boucle a fini sur une erreur ou sur une fin de fichier. Ce n'est pas tout à fait pareil.

    Personnellement, j'aurais plutôt tendance à mettre les contrôles de lecture dans la boucle, et à garder eof() en test de sortie (quitte à avoir un break, un throw ou un goto pour la sortie sur erreur de lecture). Ca me parait plus propre à la relecture (on dit alors "lire le fichier jusqu'à la fin"). Mais je conçois que c'est avant tout une question de goût.

    Francois

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Bonjour,
    je rencontre effectivement des problèmes.
    Je met ce qui suis dans le fichier triangle.txt :
    triangle 1
    1 2 3
    4 5 6
    triangle 2
    7 8 9
    10 11 12
    triangle 3
    13 14 15
    16 17 18

    et j'écris le programme :

    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
    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    #include <string>
     
    int main ()
     
    {
     
     ifstream fin("triangle.txt");
     ofstream fout("resultri.txt");
     string s;// le compteur de lignes
     int i=0;// lit la première ligne
     getline(fin,s);
     
     while(!fin.eof()) 
     
    {
     
      if(i%3!=0 || i==0) {
     
        fout<<s<<"\n";
      }
      i++;
     
      getline(fin,s); 
    }
     
    fin.close();
    fout.close();
     
     
    }

    je compile en tapant gcc -Wall triFree.C -o resultatri

    et j'obtien plein d'erreurs de type :

    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     In function `int main()':
    triFree.C:10: error: `ifstream' was not declared in this scope
    triFree.C:10: error: expected `;' before "fin"
    triFree.C:11: error: `ofstream' was not declared in this scope
    triFree.C:11: error: expected `;' before "fout"

    je ne comprend pas ! J'ai mis les bons include pourtant...

    Merci pour votre aide !

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour,
    La bibliothèque standard du C++ est contenue dans le namespace "std".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::ifstream fin("triangle.txt");
    std::ofstream fout("resultri.txt");
    std::string s;// le compteur de lignes
    // etc

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Bonjour,
    En effet j'avais oublié les std,
    j'ai donc rajouté ces derniers comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std :: ifstream fin("triangle.txt");
    std :: ofstream fout("resultri.txt");
    std :: string s;// le compteur de lignes 
     
    std :: int i=0;// lit la première ligne

    les messages d'erreurs sont (j'ai appelé mon fichier triFree.C)

    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    triFree.C: In function `int main()':
    triFree.C:15: error: expected unqualified-id before "int"
    triFree.C:15: error: expected `;' before "int"
    triFree.C:23: error: `i' was not declared in this scope
    triFree.C:25: error: `fout' is not a member of `std'
    triFree.C:27: error: `i' was not declared in this scope
    triFree.C:27: warning: unused variable 'i'
    On dirait vraiment qu'il voit rien du tout...

  11. #11
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    On dirait vraiment qu'il voit rien du tout...
    Non, non, le compilateur voit très bien...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::int i = 0; // gné ?
    ps: utilise les balises [code*][/code*] (sans l'étoile) stp, c'est plus simple à lire.

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Hmm, dans ce cas , j'ai des messages de ce type, ce que j'avais deja en mettant un
    using namespace std (et sans rajouté les std après bien sur)


    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /tmp/ccLp3Ig4.o(.text+0x52): In function `std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
    : undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const'
    /tmp/ccLp3Ig4.o(.text+0x182): In function `std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
    : undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned long) const'
    /tmp/ccLp3Ig4.o(.text+0x2a2): In function `std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':

  13. #13
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut
    "int" n'est pas un type de std. C'est un type de base.
    Bref, tu ne peux pas mettre std:: devant un "int" (ni même un double, long, char, ...).

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Oui oui, j'ai bien compris ! mais même en enlevant le std, ça ne fonctionne pas

  15. #15
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Tu peux reposter le code complet que tu essayes de compiler en ce moment ?
    Il doit y avoir une erreur de syntaxe quelque part pour que le compilo s'emmêle à ce point...

    En attendant, pour clarifier l'utilisation des std:: et autre using namespace, il y a deux solutions :
    Soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <string>
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
       string s = "hello wordl";
       cout << s << endl;
       return 0;
    }
    soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <string>
    #include <iostream>
     
    int main()
    {
       std::string s = "hello wordl";
       std::cout << s << std::endl;
       return 0;
    }

  16. #16
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Olala, même le hello world ne marche pas... en tapant ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <string>
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
       string s = "hello wordl";
       cout << s << endl;
       return 0;
    }
    je tape : gcc -wall helloworld.C -o hello

    il me renvoi pleins d'erreurs de type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned long) const'
    /tmp/ccB9b13I.o(.text+0x4a2): In function `main':
    : undefined reference to `std::allocator<char>::allocator()'
    /tmp/ccB9b13I.o(.text+0x4d2): In function `main':
    : undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
    /tmp/ccB9b13I.o(.text+0x512): In function `main':
    : undefined reference to `std::allocator<char>::~allocator()'

  17. #17
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Okkkkkkkkkkkkkkay, je pense avoir compris.
    gcc -wall helloworld.C -o hello
    gcc c'est pour le C ! Pour le C++ il me semble qu'il faut taper :
    g++ -wall helloworld.cpp -o hello
    (A confirmer, je maitrise pas très bien GCC).

  18. #18
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Wouhou, merci ! C'est bien ça, le hello world marche bien.
    C'est vraiment mes premiers pas :-S

    J'essaye maintenant pour les triangles !

  19. #19
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Wouhou, ça marche aussi pour les triangles !

    Merci encore !

  20. #20
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    "gcc" c'est la suite de compilation qui peut compiler tous les langages supportés.

    Par défaut pour déterminer le langage à compiler "gcc" utilise l'extension des fichiers.

    Si l'extension est non standard il est possible d'indiquer explicitement le langage via l'option "-x" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -x c++ -wall helloworld.C -o hello
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

Discussions similaires

  1. Réponses: 7
    Dernier message: 22/01/2008, 15h18
  2. Réponses: 20
    Dernier message: 11/12/2007, 17h34
  3. question curiosité ofstream ifstream
    Par hibiscuit dans le forum C++
    Réponses: 7
    Dernier message: 20/09/2007, 15h18
  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