Partage
  • Partager sur Facebook
  • Partager sur Twitter

Stocker dans une variable le contenu d'un fichier

Sujet résolu
    16 novembre 2019 à 19:38:37

    Bonjour,

    Voilà mon problème, j'aimerai pouvoir stocker le contenu d'un fichier test.txt ou toute autre FD entrer en paramètre de ma fonction dans un variable qui me permettra par la suite de la parcourir et l'éditer si besoin.

    int		get_next_line(int fd, char **line)
    {
    	int		test;
    	char	**tab;
    
    	if (!(tab = (char **)malloc(sizeof(tab) + 2)))
    		return (NULL);
    
    	if (fd < 0 || !line)
    		return (-1);
    	test = read(fd, tab, BUFFER_SIZE);  // BUFFER SIZE = 32
    	
    }

    Donc voici mon code pour l'instant car j'essaye de comprendre le fonctionnement de read pour faire ma fonction get_next_line.

    voici mon main pour faire mes tests.

    int        main(void)
    {
        int res;
        char **line;
        int fd;
    
        fd = open("test.txt", O_RDONLY);
        if (!(line = (char **)malloc(sizeof(line) + 2)))
            return (0);
        while ((res = get_next_line(fd, line)) > 0)
        {
            printf("%d | %s\n", res, *line);
            free(*line);
        }
        printf("%d | %s\n", res, *line);
        free(*line);
        close(fd);
        while(1){}
        return (0);
    }

    je n'ai le droit d'utiliser que read, malloc et free dans ma fonction GNL, donc si vous avez un idée qui me permettra d'avancer je suis preneur. Merci

    -
    Edité par Med_Wo 16 novembre 2019 à 19:38:53

    • Partager sur Facebook
    • Partager sur Twitter
      21 novembre 2019 à 9:04:48

      Bonjour,

      1 : un fail malloc qui renvoit 0 ? Si tu veux respecter "la norme Epitech" le 84 me paraît plus logique :)

      2 : dans ta fonction GNL tu renvoies un NULL dans une fonction qui renvoie un int

      3 : Tab est un double tableau. Tu le passes à Read alors qu'il prend un void *buff.

      4 : la valeur de fd n'est pas vérifiée avant d'être utilisé

      Je pense que la plupart des personnes ici savent que c'est un projet Epitech, je pense pas que tu recevra énormément d'aide pour l'algo. 

      Sinon bonne chance pour ton projet :)

      -
      Edité par P. Astek 21 novembre 2019 à 10:28:14

      • Partager sur Facebook
      • Partager sur Twitter
        21 novembre 2019 à 9:27:48

        C'est pas super élégant les doubles pointeurs, par contre je comprends pas la nécessité d'allouer dynamiquement dans ta fonction alors que tu lis juste après d'une taille fixe. De manière générale, en C on aime bien que les fonctions allouent le moins possible d'elle même et que ce soit à l'appelant de fournir un buffer déjà alloué avec sa taille.

        C'est pour ça que les 3/4 des fonctions de gestion de texte, affichage en C prennent souvent un char * et un size_t l'accompagnant. En revanche, si tu souhaites vraiment allouer dynamiquement une chaîne dans une fonction en le passant en paramètre tu pourrais opter pour une solution basée sur stat.

        // Pas testé mais voilà l'idée
        int readall(char **result)
        {
            int fd;
            struct stat st;
        
            if ((fd = open("test.txt", O_RDONLY)) < 0)
                return -1;
            if (fstat(fd, &st) < 0) {
                close(fd);
                return -1;
            }
            if (!(*result = calloc(st.st_size + 1, 1))) {
                close(fd);
                return -1;
            }
        
            // il faudrait idéalement tester read aussi...
            read(fd, *result, st.st_size);
            close(fd);
        
            return 0;
        }



        • Partager sur Facebook
        • Partager sur Twitter

        git is great because Linus did it, mercurial is better because he didn't.

          23 novembre 2019 à 12:56:28

          Salut @Pastèque du 44 et @Markand, j'ai régler mon problème mon buf s'occupe de stocker le contenu lu par read et j'ai terminer ma fonction. 

          Et le code que j'avais share est complétement pourri :lol:

          PS : Je ne fait pas partie d'Epitech mais de 42 :)

          int				get_next_line(int fd, char **line)
          {
          	char			buf[BUFFER_SIZE + 1];
          	static char		*rest = NULL;
          	int				ret;
          	int				i;
          	char			*tmp;
          
          	if (fd < 0 || !line)
          		return (-1);
          	while ((ret = read(fd, buf, BUFFER_SIZE)) > 0 ||
          		check_backslash_n(buf, rest) != -1)

          -
          Edité par Med_Wo 23 novembre 2019 à 13:04:38

          • Partager sur Facebook
          • Partager sur Twitter
            23 novembre 2019 à 14:02:00

            Ça fait bizarre de voir du C écrit avec des règles de codage périmées depuis 40 ans (c'est peut-être pour cela qu'on l'appelle école 42?).

            Une question. Pourquoi le cas où fd est nul est considéré comme valide?
            Une autre. Pourquoi réserver dans buf[] un caractère de plus dont la valeur est aléatoire?
            Une autre. Pourquoi le static? C'est surement dû au reste du code que l'on ne voit pas.
            Mais le caractère de plus est quant à lui un vrai problème.

            • Partager sur Facebook
            • Partager sur Twitter

            En recherche d'emploi.

              24 novembre 2019 à 18:35:49

              Salut Dalfab,

              Très bonne remarque, cela nous force a chercher et créer des solutions à nos problèmes, plutôt que d'en utiliser des toutes faites je pense..

              1er Question :

              Effectivement je n'ai pas pris en compte ce cas d'erreurs pouvant venir de l'utilisateur. 

              2e Question :

              J'alloue dynamiquement une case supplémentaire a mon buf, car dans la suite de mon code  je lui donne '\0' pour pouvoir le parcourir avec ma function "check_backslash_n".

              3e Question :

              Le but de ma fonction get_next_line est de lire n'importe quel texte/fichier depuis n'importe quel fd jusqu'au premier '\n', mon static me permet de stocker mon reste de texte après le premier '\n' rencontrer, tandis que l'autre parti est envoyer dans mon line.

              ex : J'ai un BUFFER_SIZE de 10, ce qui me permettra de lire 10 caractère de mon texte/fichier, si dans ses 10 char je rencontre un '\n', je copie la partie avant le premier '\n' dans *line, et la parti après mon '\n' dans mon static rest ce qui me permettra de reprendre au prochaine appel de ma fonction la ou je me suis arrêter jusqu'au EOF.

              ex : BUFFER_SIZE = 10; read lit -> ABCDE'\n'FGHI

              je dup ABCDE dans *line.

              et le reste lu par read FGHI dans mon statict char *rest.

              J'ai simplifier grandement les explications, mon code est un peux plus complexe que sa :D

              • Partager sur Facebook
              • Partager sur Twitter
                25 novembre 2019 à 1:31:43

                D'accord pour la 1ère et la 3ème.
                Quand à la 2nde, il faut donc mettre cet octet à 0 avant d'appeler check_backslash_n.
                • Partager sur Facebook
                • Partager sur Twitter

                En recherche d'emploi.

                  25 novembre 2019 à 9:20:12

                  Moi je ne suis pas d'accord pour le 3.

                  Ta fonction ne sera pas thread safe et retourner une variable local statique c'est un peu comme retourner une variable globale « cachée ». C'est pas très propre et peu recommandable.

                  Certaines fonction en C font ça mais pour des raisons de performances, maintenant on aurait quand même tout à y gagner à fournir le buffer en paramètre que la fonction soit réentrante et thread-safe.

                  • Partager sur Facebook
                  • Partager sur Twitter

                  git is great because Linus did it, mercurial is better because he didn't.

                    3 décembre 2019 à 23:41:10

                    Salut Dalfav et Markand,

                    C'est exactement ce que je fait dans mon code Dalfab, 

                    while ((ret = read(fd, buf, BUFFER_SIZE)) > 0 || i != -1)
                    	{
                    	  buf[ret] = '\0';
                    	  rest = ft_strjoin(rest, buf);
                    	  i = check_backslash_n(buf, rest);

                    Et pour markand en soit ce que retourne mon gnl est un int et nom ma variable static, j'utilise uniquement ma variable static pour stocker ce que mon buf a lu et ensuite le copier dans mon line.

                    int	read_file(int fd, char **line)

                    Appel de ma fonction dans le main 

                    get_next_line(fd, &line)



                    J'ai réussi a valider mon project donc tout est bon de mon coter, il est vrai que je peux en revanche améliorer mon code pour le rendre plus optimiser, mais je m'en occuperai par la suite ^^
                     

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Stocker dans une variable le contenu d'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