Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Préprocesseur]Impossible de faire une condition

Sujet résolu
    6 avril 2008 à 9:55:24

    Bonjour Zeros,
    J'ai une boucle while qui fait un certain nombre d'iteration, et je voudrais qu'a la premiere iteration elle ouvre un fichier que j'ai defini puis l'efface, puis ensuite aux autres itérations elle l'ouvre et ecris a la suite.
    J'ai donc essayé ce code qui est dans ma boucle while et malheuresement ne veut pas fonctionner :

    1. /* code simplifié */
    2. int i = 0;
    3. while(i < 8)
    4. {
    5. /* Code a part */
    6. #ifndef dejaLu
    7. cout << "Non Defini" << endl;
    8. ofstream file_2("lol.txt", ios::out | ios::trunc);
    9. #define dejaLu
    10. #else
    11. cout << "Deja Defini" << endl;
    12. ofstream file_2("lol.txt", ios::out | ios::app);
    13. #endif
    14. /* ici l'ecriture dans le fichier */
    15. i++;
    16. }


    Merci de m'aider :)
    • Partager sur Facebook
    • Partager sur Twitter
      6 avril 2008 à 12:15:51

      Lors de ta condition du préprocesseur, tu crées un flux qui te permet l'écriture dans le fichier "lol.txt"
      Le flux est créé, le fichier s'il existait avant l'éxecution du programme est vidé (ios::trunc).
      Lors de ta 2ème itération, ton flux existe déjà, il est inutile de le recréer (second "ofstream file2..."). Tu peux directement le manipuler ( file2 << ... ).

      Il ne faut pas confondre, le paramètre 'ios:trunc' va vider le fichier en question, mais ne supprimera pas.
      • Partager sur Facebook
      • Partager sur Twitter
        6 avril 2008 à 12:25:22

        Tu a en effet raison, seulement voila lorsque je fais ca :
        1. #ifndef dejaLu
        2.         cout << "Non Defini" << endl;
        3.         ofstream file_2(crypted, ios::out | ios::trunc);
        4.         #define dejaLu
        5.         #endif


        Ca me fait pareil, ca m'affiche deux fois "Non Defini", alors que ca devrait le faire qu'a la premiere itération.
        • Partager sur Facebook
        • Partager sur Twitter
          6 avril 2008 à 12:34:39

          Je pense que vous comprenez pas le rôle du préprocesseur. Il est appellé une fois, à la compilation de votre code source. Par exemple :

          Code source d'origine :
          1. /* code simplifié */
          2. int i = 0;
          3. while(i < 8)
          4. {
          5. /* Code a part */
          6. #ifndef dejaLu
          7. cout << "Non Defini" << endl;
          8. ofstream file_2("lol.txt", ios::out | ios::trunc);
          9. #define dejaLu
          10. #else
          11. cout << "Deja Defini" << endl;
          12. ofstream file_2("lol.txt", ios::out | ios::app);
          13. #endif
          14. /* ici l'ecriture dans le fichier */
          15. i++;
          16. }


          Code à la sortie du préprocesseur :
          1. int i = 0;
          2. while(i < 8)
          3. {
          4. cout << "Non Defini" << endl;
          5. ofstream file_2("lol.txt", ios::out | ios::trunc);
          6. i++;
          7. }


          Ça devrait vous aider à voir la cause du problème.
          • Partager sur Facebook
          • Partager sur Twitter
            6 avril 2008 à 12:47:15

            Est ce que le fait de mettre #endif avant #else résout le problème? Pour moi cette disposition serait plus logique. Mais ne connaissant pas très bien les règles du préprocesseur j'ignore le résultat de cette modification.

            • Partager sur Facebook
            • Partager sur Twitter
              6 avril 2008 à 12:56:27

              Ah d'accord, maintenant il me faut un moyen pour effacer le fichier juste a la premiere itération.
              • Partager sur Facebook
              • Partager sur Twitter
                6 avril 2008 à 13:02:53

                o_O Le préprocesseur s'execute à la compilation pas lors de l'execution... Pour ça il y'a les conditions...
                • Partager sur Facebook
                • Partager sur Twitter
                  6 avril 2008 à 13:10:46

                  Bon j'ai essayé comme ca :
                  1. int i = 0, it = 0;
                  2. while(i < 8)
                  3. {
                  4. if(it == 0)
                  5.         {
                  6.         cout << "Non Defini" << endl;
                  7.         ofstream file_2(crypted, ios::out | ios::trunc);
                  8.         }
                  9. file_2 << "Texte"+i;
                  10. it++;
                  11. }

                  Ca me dit file_2 was not declared comme si le code de la condition ne s'execute pas
                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 avril 2008 à 13:39:14

                    C'est pas un truc que tu peux faire avec le préprocesseur. Le préprocesseur ne sert qu'a spécialiser la compilation ici la traduction de ton code sera après traitement par le préprocesseur

                    1. /* code simplifié */
                    2. int i = 0;
                    3. while(i < 8)
                    4. {
                    5. /* Code a part */
                    6. cout << "Non Defini" << endl;
                    7. ofstream file_2("lol.txt", ios::out | ios::trunc);
                    8. /* ici l'ecriture dans le fichier */
                    9. i++;
                    10. }


                    Les directives du préprocesseur sont appliquée avant la compilation du code. Le code qui a été écarté par le préprocesseur n'est carrément par compilé dans le programme. En règle générale, on utilise le préprocesseur pour isoler du code très spécifique.

                    1. #ifdef WIN32  
                    2. // WIN32 est un define défini par Microsoft pour indiquer qu'on compile du code pour Windows
                    3. const std::string myFileName = "c:\\myfile.txt";
                    4. #else
                    5. const std::string myFileName = "/myfile.txt";
                    6. #endif


                    Ce code se traduit par: Si je compile mon programme pour Windows, la chaine myFileName vaudra c:\myfile.txt, sinon elle vaudra /myfile.txt

                    Tu as sans doute mal compris le principe des garde anti-réinclusion dans les en-têtes.

                    1. // header1.h
                    2. class toto {
                    3. public:
                    4.     toto(){};
                    5. };


                    1. // header2.h
                    2. #include "header1.h"
                    3. class titi
                    4. {
                    5. public:
                    6.     titi(const toto & ){};
                    7. };


                    1. // header3.h
                    2. #include "header1.h"
                    3. class tutu
                    4. {
                    5. public:
                    6.     tutu(const toto & ){};
                    7. }


                    1. // main.cpp
                    2. #include "header2.h"
                    3. #include "header3.h"
                    4. int main()
                    5. {
                    6.     toto t;
                    7.     titi ti(t);
                    8.     tutu tu(t);
                    9.     return 0;
                    10. }


                    Le préprocesseur va construire le fichier source à compiler en analysant chaque clause

                    Il va commencer par #include "header2.h" qui inclus lui même header1.h, le fichier à compiler commencera donc par le contenu de header1.h, puis le contenu de header2.h. Ensuite il va analyser #include "header3.h", qui inclus lui même header1.h, donc il va remettre le contenu de header1.h avant le contenu de header3.h. Enfin il ajoutera le code contenu dans main.cpp.

                    Finalement le code passé au compilateur sera le suivant

                    1. class toto {
                    2. public:
                    3.     toto(){};
                    4. };
                    5. class titi
                    6. {
                    7. public:
                    8.     titi(const toto & ){};
                    9. };
                    10. class toto {
                    11. public:
                    12.     toto(){};
                    13. };
                    14. class tutu
                    15. {
                    16. public:
                    17.     tutu(const toto & ){};
                    18. }
                    19. int main()
                    20. {
                    21.     toto t;
                    22.     titi ti(t);
                    23.     tutu tu(t);
                    24.     return 0;
                    25. }


                    Le compilateur va trouver une redéfinition de la classe toto et va donc générer une erreur. Pour éviter ce problème on utilise une garde anti réinclusion. Si je modifie header1.h de la façon suivante

                    1. #ifndef HEADER1_INCLUDED
                    2. #define HEADER1_INCLUDED
                    3. class toto
                    4. {
                    5. public:
                    6.     toto(){};
                    7. }
                    8. #endif // HEADER1_INCLUDED


                    Quand le préprocesseur prépare la compilation de main.cpp, il va analyser les include comme précédemment, sauf que la première fois qu'il va tomber sur un #include "header1.h", HEADER1_INCLUDED ne sera pas défini, donc il va le définir, et ajouter la définition de la classe toto dans le module à compiler. Lorsqu'il va retomber sur une ligne #include "header1.h", cette fois-ci, HEADER1_INCLUDED sera défini, il va donc sauter tout ce qui se trouve jusqu'au #else ou #endif correspondant au #ifndef. Ici il n'ajoutera donc pas une deuxième fois la définition de la classe toto.

                    Il faut également savoir que le préprocesseur est invoqué avant la compilation de chaque fichier cpp.

                    Pour le problème de ton dernier code, c'est un problème de portée, ton ofstream est déclarée dans le if, il n'existe pas en dehors du bloc du if. Il me semble plus judicieux de créer le ofstream avant d'entrer dans le while.


                    • Partager sur Facebook
                    • Partager sur Twitter
                    Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                      6 avril 2008 à 14:38:54

                      Merci pour vos aides, j'ai enfin trouvé la solution, j'ai declaré la fonction ofstream en dehors de la boucle while et dans la boucle while a la fin j'ai mis :
                      1. file_2 << "Texte"+i; // ou  i est le numero de l'iteration

                      Encore merci a tous et surtout a int21h pour ses précision :)
                      • Partager sur Facebook
                      • Partager sur Twitter

                      [Préprocesseur]Impossible de faire une condition

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown