Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ecrire dans un fichier

Pourtant simple mais...

    26 septembre 2022 à 12:59:11

    Bonjour j'ai un sujet que je trouve assez simple et ça me rend fou de pas pouvoir le résoudre. Merci d'avance

    J'ai ce bout de code

    int main(){
    FILE *Fichier;
    Fichier = fopen("Gen_stat.txt","r+");
    
        if(fgetc(Fichier)==EOF){
    
            printf("\n\tFichier vide");
            fprintf(Fichier,"\n\tMARSEILLE - PARIS");
    
        }
        else{
    
            printf("\n\n\tFICHIER BEL ET BIEN REMPLI");
            fprintf(Fichier,"\n\tBANDE ORGANISEE");
    } return 0; }

    Mon fichier n'est pas vide et je ne comprends pas pourquoi "BANDE ORGANISEE" ne s'écrit pas dans le fichier. Merci d'avance

    • Partager sur Facebook
    • Partager sur Twitter
      26 septembre 2022 à 13:20:27

      Bonjour,

      if(feof(Fichier)) {
          printf("Fichier vide !")
      } else {
          printf("Rempli")
      }
      



      -
      Edité par Phil_1857 26 septembre 2022 à 13:31:22

      • Partager sur Facebook
      • Partager sur Twitter
        26 septembre 2022 à 13:49:04

        Bonjour Phil, merci pour ta contribution

        J'ai essayé ton bout de code sauf que la première condition (celle avec le feof) n'est jamais acté même lorsque le fichier est vide

        • Partager sur Facebook
        • Partager sur Twitter
          26 septembre 2022 à 14:04:02

          Et si tu fermes le fichier (avec 'fclose') ?

          (Si j'ai bien compris, lorsqu'on fait 'fopen' le fichier est copié en mémoire vive, et les 'fwrite' écrivent dans la copie, pas dans le fichier du disque. C'est en faisant 'fclose' que la copie en mémoire vive est recopiée sur le disque. Ça doit être quelque chose comme ça.)

          -
          Edité par robun 26 septembre 2022 à 14:07:07

          • Partager sur Facebook
          • Partager sur Twitter
            26 septembre 2022 à 14:10:11

            Bonjour Robun, c'est juste dans le bout de code posté que je n'ai pas mis de fclose sinon dans mon code source il y figure bien. 

            Et malgré tout, la première condition n'est jamais vérifiée. Même quand le fichier est vide.

            -
            Edité par DannyOndaye 26 septembre 2022 à 14:11:08

            • Partager sur Facebook
            • Partager sur Twitter
              26 septembre 2022 à 15:07:37

              Il faut croire que le fichier n'est pas vide. Tu devrais peut-être afficher le caractère lu par 'fgetc'.

              Tu pourrais par exemple remplacer

               if(fgetc(Fichier)==EOF){

              par

               int c = fgetc(Fichier);
               printf("c = %d\n", c); // %d affichera le code ASCII, utile si c'est un caractère spécial
               if (c == EOF){

              Tu peux faire des essais, mettre des affichages, etc. Et vérifier que 'fclose' est au bon endroit (mets des 'printf' autour du 'fclose' pour voir si on y passe).

              Au fait, il n'y a pas des contraintes pour écrire dans un fichier ouvert en mode "r+" ?

              -
              Edité par robun 26 septembre 2022 à 15:12:42

              • Partager sur Facebook
              • Partager sur Twitter
                26 septembre 2022 à 15:26:58

                Il faut repositionner le curseur pour écrire après une lecture par exemple à la fin :

                    else
                    {
                        fseek(Fichier, 0, SEEK_END);
                        printf("\n\n\tFICHIER BEL ET BIEN REMPLI");
                        fprintf(Fichier,"\n\tBANDE ORGANISEE");
                    }



                • Partager sur Facebook
                • Partager sur Twitter
                ...
                  26 septembre 2022 à 16:16:06

                  robun a écrit:

                  Et si tu fermes le fichier (avec 'fclose') ?

                  (Si j'ai bien compris, lorsqu'on fait 'fopen' le fichier est copié en mémoire vive, et les 'fwrite' écrivent dans la copie, pas dans le fichier du disque. C'est en faisant 'fclose' que la copie en mémoire vive est recopiée sur le disque. Ça doit être quelque chose comme ça.)

                  -
                  Edité par robun il y a environ 1 heure

                  Robin le fichier était bien vide des fois puisque c'est moi qui le vidait manuellement. Et en plus de ça l'instruction avec printf située dans la même parenthèse était exécutée.

                  Ce qui veut dire que le programme se déroulait parfaitement juste que l'instruction avec fprintf n'était pas pris en compte.

                  -
                  Edité par DannyOndaye 26 septembre 2022 à 16:17:54

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 septembre 2022 à 16:19:11

                    Est-ce qu'il va chercher ton fichier au bon endroit ? donc fopen le voit-il comme existant au moins ?

                    voir ce que retourne (par exemple) ces 2 lignes mises juste après le fopen

                        printf("%d\n",errno);
                        printf("%s\n",strerror(errno));

                    avec les include <errno.h> et <string.h>

                    • Partager sur Facebook
                    • Partager sur Twitter
                      26 septembre 2022 à 16:21:17

                      J'ai essayé puis ou moins le même code à un détail près. J'ai remplacé la condition else par else if et le tout fonctionne.

                      int main(){
                      FILE *Fichier;
                      Fichier = fopen("Gen_stat.txt","r+");
                      
                          if(fgetc(Fichier)==EOF){
                      
                              printf("\n\tFichier vide");
                              fprintf(Fichier,"\n\tMARSEILLE - PARIS");
                      
                          }
                          else if(fgetc(Fichier)!=EOF){
                      
                              fclose(Fichier);
                              fopen("Gen_stat.txt","a");
                              printf("\n\tFICHIER BEL ET BIEN REMPLI");
                              fprintf(Fichier,"\n\n\n\tNOUVELLE ECOLE RAP");
                      
                          }
                          fprintf(Fichier,"\n\tBANDE ORGANISEE");
                          fclose(Fichier);
                          return 0;
                      }

                      écrit comme ça tout à l'air de bien fonctionner.

                      Quelqu'un aurait une explication please ? Pourquoi le code fonctionnerait-il avec else if et pas avec else ? o_O

                      -
                      Edité par DannyOndaye 26 septembre 2022 à 16:24:34

                      • Partager sur Facebook
                      • Partager sur Twitter
                        26 septembre 2022 à 16:29:26

                        Ce qui a fait que ça fonctionne ce n'est pas le else if mais le fait que tu as fermé et ré-ouvert ton fichier. (ce qui fait un rewind en fait). 

                        Et tu as du bol, parce que en le ré-ouvrant tu n'as pas récupéré le descripteur de fichier. (C'est donc un peu olé olé).

                        PS : Je m’aperçois que tu as zappé mon message précédent.

                        -
                        Edité par rouIoude 26 septembre 2022 à 16:30:13

                        • Partager sur Facebook
                        • Partager sur Twitter
                        ...
                          26 septembre 2022 à 17:31:28

                          c'est aussi parce que ton fichier devait contenir un caractère en début, fgetc faisant avancé le curseur (tu lis un caractère avec le 1er fgetc (du if) et tu en lis un second avec le fgetc du elseif)

                          -
                          Edité par umfred 26 septembre 2022 à 17:31:43

                          • Partager sur Facebook
                          • Partager sur Twitter
                            26 septembre 2022 à 17:59:27

                            DannyOndaye a écrit:

                            robun a écrit:

                            Et si tu fermes le fichier (avec 'fclose') ?

                            (Si j'ai bien compris, lorsqu'on fait 'fopen' le fichier est copié en mémoire vive, et les 'fwrite' écrivent dans la copie, pas dans le fichier du disque. C'est en faisant 'fclose' que la copie en mémoire vive est recopiée sur le disque. Ça doit être quelque chose comme ça.)

                            -
                            Edité par robun il y a environ 1 heure

                            Robin le fichier était bien vide des fois puisque c'est moi qui le vidait manuellement. Et en plus de ça l'instruction avec printf située dans la même parenthèse était exécutée.

                            > c'est moi qui le vidais manuellement

                            C'est ce que tu crois. Comment faisais-tu ?  Est tu sûr que ton fichier que tu crois avoir vide n'est pas composé d'une ligne vide ? Ce qui n'est pas la même chose qu"avoir un fichier vide. Faut pas croire, faut vérifier. La taille du fichier est-elle de 0 octets ?

                            > l'instruction avec printf située dans la même parenthèse était exécutée.

                            (Des accolades, pas des parenthèses, pour délimiter un bloc). C'est peut être un autre problème. Si il s'agit de

                            printf("\n\tFichier vide");

                            il est possible (ça dépend des systèmes) que la chaine de caractères "\tFichier vide" soit dans le tampon de sortie, mais n'a pas été encore envoyée à l'écran, parce qu'il n'y a pas un "\n" à la fin pour faire le "flush" du tampon de sortie.


                            > Si j'ai bien compris, lorsqu'on fait 'fopen' le fichier est copié en mémoire vive

                            Pas le fichier. Les E/S (entrées-sorties) reposent sur des tampons à plusieurs niveaux, pour minimiser le nombre de d'E/S physiques qui sont généralement (disque dur par ex.) extrêmement lentes par rapport aux opérations en mémoire.  Donc quand on fait des écritures, les données à écrire (pas tout le fichier)  sont stockées dans un tampon en mémoire un certain temps, en attendant que ça soit opportun de les envoyer au disque. Typiquement le systeme attend d'avoir un "bloc" complet à envoyer. Et bien sur, il expédie ce qui reste quand on ferme la boutique (cloture du fichier).

                            Pour les écritures sur la sortie standard, la politique habituelle est de déclencher l'écriture physique quand le caractère \n (fin de ligne). Si on veut forcer l'écriture - sur le systèmes qui en ont besoin, windows ? - il faut faire un fflush(stdout);

                            (il peut y avoir d'autres déclenchements, pour des écritures sur le réseau - Algorithme de Nagle ? - le contenu du tampon est envoyé "au bout d'un certain délai" si le tampon n'est pas plein).



                            -
                            Edité par michelbillaud 26 septembre 2022 à 18:01:10

                            • Partager sur Facebook
                            • Partager sur Twitter
                              26 septembre 2022 à 18:47:30

                              umfred a écrit:

                              c'est aussi parce que ton fichier devait contenir un caractère en début, fgetc faisant avancé le curseur (tu lis un caractère avec le 1er fgetc (du if) et tu en lis un second avec le fgetc du elseif)

                              -
                              Edité par umfred il y a environ 1 heure

                              Merci Umfred pour tes include errno et strerror que je ne connaissais pas du tout. Je vais me documenter dessus.

                              Sinon pour le fichier y avait des retour en arrière au tout début donc le caractère "\n" qui était lu je pense. Mais avec l'astuce de Rouloude de positionner le curseur ça a tout débloqué

                              • Partager sur Facebook
                              • Partager sur Twitter
                                26 septembre 2022 à 19:02:03

                                avec la méthode de robun d'afficher la valeur retour de fgetc, tu aurais trouver le problème (c'est peut-être ce que tu as fait en fait)

                                https://koor.fr/C/cstdio/fgetc.wp 

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  26 septembre 2022 à 19:13:18

                                  suffit de regarder la taille du fichier, pas besoin de trucs et astuces en C.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    26 septembre 2022 à 19:40:09

                                    umfred a écrit:

                                    avec la méthode de robun d'afficher la valeur retour de fgetc, tu aurais trouver le problème (c'est peut-être ce que tu as fait en fait)

                                    https://koor.fr/C/cstdio/fgetc.wp 


                                    Oui je pense aussi...

                                    En quelques sortes ça revient au même

                                    Donc voilà pour terminer voici le code avec les instructions correctes :

                                    int main(){
                                    FILE *Fichier;
                                    Fichier = fopen("Gen_stat.txt","r+");
                                    
                                        if(fgetc(Fichier)==EOF){
                                    
                                            printf("\n\tFichier vide");
                                            fprintf(Fichier,"\n\tMARSEILLE - PARIS");
                                    
                                        }
                                        else {///if(fgetc(Fichier)!=EOF){
                                    
                                            fseek(Fichier, 0, SEEK_END);
                                            ///fclose(Fichier);
                                            ///fopen("Gen_stat.txt","a");
                                            printf("\n\tFICHIER BEL ET BIEN REMPLI");
                                            fprintf(Fichier,"\n\n\n\tNOUVELLE ECOLE B.B. Jacques");
                                    
                                        }
                                        fprintf(Fichier,"\n\tBANDE ORGANISEE");
                                        fclose(Fichier);
                                        return 0;
                                    }

                                    Merci à vous tous en tout cas Phil_1857, Rouloude, Umfred, MichelBillaud

                                    Excellente collaboration :magicien:

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Ecrire dans un fichier

                                    × 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