Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lire et supprimer du contenu dans un fichier .txt

Suppression partielle de contenu

Sujet résolu
    22 septembre 2018 à 11:22:36

    Bonjour à tous et à toutes, 

    En espérant que tout va bien pour vous, moi je suis légèrement bloqué sur un TP que j'ai quasiment fini mais à qui il manque encore une fonctionnalité. Alors je vous explique en classe on a abordé les piles et le but du tp était de répresenter les données de piles de trois manières, sur la console, avec des node_t et maintenant en l'affichant sur un fichier .txt. 

    Le programme doit insérer des valeurs dans le style des piles (LIFO) et doit les dépiler également. J'arrive à tout faire (lecture de fichier, écriture sur le fichier) sauf le dépiler. J'ai essayé de jouer avec les fgetc afin de récupérer le pointeur de la valeur pour chaque ligne mais malheureusement j'échoue. Je sais que je suis très proche du but mais un petit coup de main ne serait pas de refus. 

    Je vous mets les codes sources pour chaque partie du coup

    stack_file.h

    #ifndef STACK_FILE_H_INCLUDED
    #define STACK_FILE_H_INCLUDED
    
    #define MAX_FLNM 100
    typedef struct {
     char filename[MAX_FLNM];
     int fd; // file descriptor of the open file
     int top_off; // final offset
    } stack_t;
    void set_file(stack_t *); // special function to determine the file to be used
    void init_stack(stack_t*); // initalize the data structure
    int push_stack(stack_t *, int); // push value into stack
    int pop_stack(stack_t *, int *); // pops top value from stack;
    int top_stack(stack_t *, int *); // returns top value of stack
    void display_stack(stack_t *); // displays the contents of the stack
    
    #endif // STACK_FILE_H_INCLUDED
    

    stack_file.c

    #include <stdio.h>"
    #include "stack_file.h"
    #include <string.h>
    
    
    void set_file(stack_t *s)
    {
        FILE* file;
        file=fopen("file.txt","w+");
        printf("test set \n");
    }
    void init_stack(stack_t* s)
    {
        char nom []="file.txt";
        strcpy(s->filename,nom);
        s->fd=fopen("file.txt", "w+");
        s->top_off=0;
        printf("test init \n");
    
    
    
    } // initalize the data structure
    int push_stack(stack_t* s, int val)
    {
            printf("test push \n");
        fseek (s->fd, 0, SEEK_END);
        fprintf(s->fd, "%d \n",val);
    
    
    } // push value into stack
    int pop_stack(stack_t* s, int *val)
    {
    
        fseek(s->fd,0,SEEK_CUR);
        fputs("",s->fd);
        *val=fgetc(s->fd);
        printf("test pop \n");
    
        }
     // pops top value from stack;
    //int top_stack(stack_t *, int *); // returns top value of stack
    void display_stack(stack_t* s)
    {
            printf("test display \n");
    
        fopen(s->fd,"r+");
    
    } // displays the contents of the stack
    
    

    main.c 

    #include <stdio.h>
    #include <stdlib.h>
    #include "stack_file.h"
    int main() {
     stack_t p;
     set_file(&p);
     init_stack(&p);
     push_stack(&p, 5);
     push_stack(&p, 6);
     push_stack(&p, 7);
     display_stack(&p);
     scanf("%*c");
     int val;
     pop_stack(&p, &val);
     printf("popped value = %d\n", val);
     display_stack(&p);
     pop_stack(&p, &val);
     printf("popped value = %d\n", val);
     display_stack(&p);
     pop_stack(&p, &val);
     printf("popped value = %d\n", val);
     display_stack(&p);
     pop_stack(&p, &val); // fails
     printf("popped value = %d\n", val); // prints out the old value
     display_stack(&p);
    
    
    }
    
    

    Du coup la fonction pop_stack renvoie un pointeur sur la valeur qui a été dépilée, le problème c'est que je n'arrive pas à trouver un moyen à avoir accès à cette valeur, mais je sais que ça tourne autour de fseek et de fgetc. Hésitez pas à me donner des conseils sur le code aussi si je fais des choses inutiles, moi de mon côté je continue à chercher les fonctions dans le stdio.h qui pourront m'aider.

    Merci à tous ceux qui m'aideront et bonne journée!




    -
    Edité par FaresK 22 septembre 2018 à 11:23:04

    • Partager sur Facebook
    • Partager sur Twitter
      22 septembre 2018 à 13:20:16

      Hello,

      Tu dois avoir pas mal de warnings (si pas des erreurs): fopen() renvoie un pointeur (FILE *), pas un descripteur (un int).

      Ou tu emploies les fonctions de io.h (open, read, write, close) avec un file descriptor (un int), ou tu emploies celles de stdio.h (fopen, fread, fwrite, fclose) avec un pointeur (FILE *). Parce que, ligne 16 par exemple, fd=fopen(), ça va pas le faire.

      -
      Edité par edgarjacobs 22 septembre 2018 à 13:24:59

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        22 septembre 2018 à 17:13:32

        Hello @edgarjacobs,

        Merci d'avoir répondu.

        Je t'assure que de ce côté j'ai ni warning ni error. La fonction d'écriture arrive à écrire ce qui est demandé, le seul souci que j'ai c'est le pop_stack qui lui j'arrive pas à trouver. 

        • Partager sur Facebook
        • Partager sur Twitter
          22 septembre 2018 à 17:36:35

          Re,-

          Fares Kissoum a écrit:

          Je t'assure que de ce côté j'ai ni warning ni error

          Les options de ton compilateur son mal réglées.

          D'abord les erreurs, puis le code compilé (gcc 6.3.0, options -std=c11 -Wall -Wextra):

          stack.c: In function 'set_file':
          stack.c:26:11: warning: variable 'file' set but not used [-Wunused-but-set-variable]
               FILE* file;
                     ^~~~
          stack.c:24:24: warning: unused parameter 's' [-Wunused-parameter]
           void set_file(stack_t *s)
                                  ^
          stack.c: In function 'init_stack':
          stack.c:34:10: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
               s->fd=fopen("file.txt", "w+");
                    ^
          stack.c: In function 'push_stack':
          stack.c:44:12: warning: passing argument 1 of 'fseek' makes pointer from integer without a cast [-Wint-conversion]
               fseek (s->fd, 0, SEEK_END);
                      ^
          In file included from stack.c:19:0:
          c:\mingw\include\stdio.h:739:41: note: expected 'FILE * {aka struct _iobuf *}' but argument is of type 'int'
           _CRTIMP __cdecl __MINGW_NOTHROW  int    fseek (FILE *, long, int);
                                                   ^~~~~
          stack.c:45:13: warning: passing argument 1 of 'fprintf' makes pointer from integer without a cast [-Wint-conversion]
               fprintf(s->fd, "%d \n",val);
                       ^
          In file included from stack.c:19:0:
          c:\mingw\include\stdio.h:403:5: note: expected 'FILE * {aka struct _iobuf *}' but argument is of type 'int'
           int fprintf (FILE *__stream, const char *__format, ...)
               ^~~~~~~
          stack.c: In function 'pop_stack':
          stack.c:52:11: warning: passing argument 1 of 'fseek' makes pointer from integer without a cast [-Wint-conversion]
               fseek(s->fd,0,SEEK_CUR);
                     ^
          In file included from stack.c:19:0:
          c:\mingw\include\stdio.h:739:41: note: expected 'FILE * {aka struct _iobuf *}' but argument is of type 'int'
           _CRTIMP __cdecl __MINGW_NOTHROW  int    fseek (FILE *, long, int);
                                                   ^~~~~
          stack.c:53:14: warning: passing argument 2 of 'fputs' makes pointer from integer without a cast [-Wint-conversion]
               fputs("",s->fd);
                        ^
          In file included from stack.c:19:0:
          c:\mingw\include\stdio.h:675:41: note: expected 'FILE * {aka struct _iobuf *}' but argument is of type 'int'
           _CRTIMP __cdecl __MINGW_NOTHROW  int    fputs (const char *, FILE *);
                                                   ^~~~~
          stack.c:54:16: warning: passing argument 1 of 'fgetc' makes pointer from integer without a cast [-Wint-conversion]
               *val=fgetc(s->fd);
                          ^
          In file included from stack.c:19:0:
          c:\mingw\include\stdio.h:672:41: note: expected 'FILE * {aka struct _iobuf *}' but argument is of type 'int'
           _CRTIMP __cdecl __MINGW_NOTHROW  int    fgetc (FILE *);
                                                   ^~~~~
          stack.c: In function 'display_stack':
          stack.c:64:11: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast [-Wint-conversion]
               fopen(s->fd,"r+");
                     ^
          In file included from stack.c:19:0:
          c:\mingw\include\stdio.h:260:41: note: expected 'const char *' but argument is of type 'int'
           _CRTIMP __cdecl __MINGW_NOTHROW  FILE * fopen (const char *, const char *);
                                                   ^~~~~
          stack.c: In function 'push_stack':
          stack.c:48:1: warning: control reaches end of non-void function [-Wreturn-type]
           } // push value into stack
           ^
          stack.c: In function 'pop_stack':
          stack.c:57:5: warning: control reaches end of non-void function [-Wreturn-type]
               }
               ^
          
          #ifndef STACK_FILE_H_INCLUDED
          #define STACK_FILE_H_INCLUDED
           
          #define MAX_FLNM 100
          typedef struct {
           char filename[MAX_FLNM];
           int fd; // file descriptor of the open file
           int top_off; // final offset
          } stack_t;
          void set_file(stack_t *); // special function to determine the file to be used
          void init_stack(stack_t*); // initalize the data structure
          int push_stack(stack_t *, int); // push value into stack
          int pop_stack(stack_t *, int *); // pops top value from stack;
          int top_stack(stack_t *, int *); // returns top value of stack
          void display_stack(stack_t *); // displays the contents of the stack
           
          #endif // STACK_FILE_H_INCLUDED
          
          #include <stdio.h>
          // #include "stack_file.h"
          #include <string.h>
           
           
          void set_file(stack_t *s)
          {
              FILE* file;
              file=fopen("file.txt","w+");
              printf("test set \n");
          }
          void init_stack(stack_t* s)
          {
              char nom []="file.txt";
              strcpy(s->filename,nom);
              s->fd=fopen("file.txt", "w+");
              s->top_off=0;
              printf("test init \n");
           
           
           
          } // initalize the data structure
          int push_stack(stack_t* s, int val)
          {
                  printf("test push \n");
              fseek (s->fd, 0, SEEK_END);
              fprintf(s->fd, "%d \n",val);
           
           
          } // push value into stack
          int pop_stack(stack_t* s, int *val)
          {
           
              fseek(s->fd,0,SEEK_CUR);
              fputs("",s->fd);
              *val=fgetc(s->fd);
              printf("test pop \n");
           
              }
           // pops top value from stack;
          //int top_stack(stack_t *, int *); // returns top value of stack
          void display_stack(stack_t* s)
          {
                  printf("test display \n");
           
              fopen(s->fd,"r+");
           
          } // displays the contents of the stack
          
          #include <stdio.h>
          #include <stdlib.h>
          //#include "stack_file.h"
          
          int main() {
           stack_t p;
           set_file(&p);
           init_stack(&p);
           push_stack(&p, 5);
           push_stack(&p, 6);
           push_stack(&p, 7);
           display_stack(&p);
           scanf("%*c");
           int val;
           pop_stack(&p, &val);
           printf("popped value = %d\n", val);
           display_stack(&p);
           pop_stack(&p, &val);
           printf("popped value = %d\n", val);
           display_stack(&p);
           pop_stack(&p, &val);
           printf("popped value = %d\n", val);
           display_stack(&p);
           pop_stack(&p, &val); // fails
           printf("popped value = %d\n", val); // prints out the old value
           display_stack(&p);
           
           
          }
          



          -
          Edité par edgarjacobs 22 septembre 2018 à 17:39:46

          • Partager sur Facebook
          • Partager sur Twitter

          On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

            23 septembre 2018 à 14:58:42

            Bonjour,

            Toutes les fonctions présentent un défaut, il va falloir les relire.
            D'autre part je n'arrive pas à relier ton code à l'énoncé. D'autant que que tu parles bien de stack ou de LIFO. Vue la structure de fichier que tu utilises (qui t'a peut-être été préconisée dans l'énoncé), le seul mécanisme implémentable est celui d'une FIFO (c-a-d une queue) donc le premier élément à extraire serait celui au début du fichier. Il manque des marqueurs ou le fichier devrait être à minima binaire. Difficile de t'aider sans mieux connaître l'énoncé et tes contraintes.

            La première fonction set_file():
            - elle reçoit un paramètre dont elle n'a rien à carrer!
            - elle ouvre un fichier et le crée vide s'il n'existe pas, mais perd le handle car il reste local à la fonction. Et donc se fichier restera bloqué ouvert jusqu'à la terminaison du programme (impossible de le refermer). Ce fichier sera réouvert en simultané ailleurs dans le code.

            La seconde fonction init_stack():
            - elle réouvre le fichier (elle connaît elle aussi son nom) mais stocke le handle dans un int. A ma connaissance c'est une erreur, les types sont incompatibles et ne sont même pas garantis de tailles identiques. Je suis étonné que gcc n'indique pas une erreur, et je n'imagine pas ce warning invisible.

            La troisième fonction push_stack():
            - c'est pas trop mal.
            - Mais pourquoi donc le s->top_off n'est pas mis à jour? Il faudrait comprendre à quoi il peut servir et donc relire l'énoncé.

            ...

            • Partager sur Facebook
            • Partager sur Twitter

            En recherche d'emploi.

            Lire et supprimer du contenu dans un fichier .txt

            × 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