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 :

Lire au-delà du buffer, fonction get_next_ligne


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de awesomeman
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 166
    Par défaut Lire au-delà du buffer, fonction get_next_ligne
    Bonjour,
    Je viens demander des conseils par rapport à ma fonction get_next_line, qui doit à chaque fois qu'elle est appelé , écrire la ligne suivante d'un fichier texte.
    J'ai un problème concernant le buffer , en fait le READ_SIZE (taille de buffer) peut etre inférieur au nombre de caractères de l'ensemble du fichier or il faut que je sois capable de lire toutes les lignes si on me le demande (comme c'est le cas avec le main ci dessous).
    Pour l'instant j'affiche correctement les trois première lignes d'u fichier mais la lecture du fichier s'arrete avec la taille du buffer .Mon but est donc d'affiché le reste du fichier jusqu'au bout (sans modifier directement le READ_SIZE).

    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 <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include "get_next_line.h"
     
    char	*get_next_line(const int fd)
    {
      char *string;
      static char buff[READ_SIZE];
      static int z;
      static int cmp;
      int y;
     
      y = 0;
      string = malloc(READ_SIZE * z);
      z = read(fd, buff, READ_SIZE);
      while (buff[cmp] != '\n')
        {
          string[y] = buff[cmp];
          if (buff[cmp] == '\0')
    	{
    	  return(0);
    	}
          cmp += 1;
          y += 1;
        }
      if (buff[cmp] == '\n')
        cmp += 1;
      string[y] = 0;
      return (string);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int	main(int ac, char **av)
    {
      char *s;
      while ((s = get_next_line(open(av[1], O_RDONLY))))
        {
          my_putstr(s);
          my_putchar('\n');
          free(s);
        }
      return 0;
    }
    n'hesitez pas si vous avez des question

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par awesomeman Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      static int z;
      static int cmp;
      int y;
     
      y = 0;
      string = malloc(READ_SIZE * z);
      z = read(fd, buff, READ_SIZE);
    WAT WAT WAT !? Tu nous fais quoi là, du séquentiel inversé ?

    Pourquoi as-tu un buffer statique en plus d'une allocation dynamique ? Si tu ne peux pas faire ce que tu veux en statique comme tu le dis, utilise uniquement la méthode dynamique.

    Qu'est-ce qui te pose des difficultés en particulier ?

  3. #3
    Membre confirmé Avatar de awesomeman
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 166
    Par défaut
    ah oui ca c'est n'importe quoi j'avais oublié de changer

    En gros , mon problème est que je ne sais pas comment lire mon fichier au de la de taille du buffer , pour l'instant je peux lire tout le fichier (uniquement si mon buffer est supérieur ou égal à mon nombre de caractère ).
    Par contre si par exemple on m'envoie comme READ_SIZE 10 et que le nombre de caractère de mon est fichier est 100 , c'est mort.. j'arriverai à affiché uniquement jusqu'a 10. Il me faut donc sans toucher à la valeur de READ_SIZE, pouvoir lire tout mon fichier ligne par ligne dans le cas ou READ_SIZE < nb caractère .

    Je suis obligé d'utiliser au moins une static .

    PS : je ne peux utiliser que es fonction read, malloc, free

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ah, un épitarque

    Pour ton problème, il va te falloir lire en boucle. Et si la ligne est plus grande que le buffer, agrandir le buffer au fur et à mesure (ou faire une liste chaînée que tu concatènes tout à la fin).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par awesomeman Voir le message
    Je suis obligé d'utiliser au moins une static .

    PS : je ne peux utiliser que es fonction read, malloc, free
    C'est mieux avec ces précisions. On comprend ce que le prof cherche à vous faire écrire : la fonction doit modifier le descripteur de fichier et renvoyer le contenu de la ligne en cours à chaque appel, dans un buffer dont elle prend en charge l'allocation mémoire.

    Au passage je dissipe une source de confusion que j'ai créée avant : je ne faisais pas référence au fait que ton buffer initial soit marqué static mais au fait que son allocation était réalisée de façon statique au démarrage du programme.

    Maintenant, comme tu vas lire avec read par bloc de taille READ_SIZE et que tu ne renvoies qu'une seule ligne à la fois, il te faut stocker les premiers caractères de la ligne suivante quelque part (sauf si tu ne lis que des fichiers dont les tailles des lignes sont toutes des multiples de READ_SIZE ) et la déclaration du buffer de destination statique et static fait ainsi sens.

    Comme l'a dit Médinoc il te faut donc une boucle de lecture à l'intérieur de la fonction. N'oublie pas le cas où plusieurs lignes peuvent être contenues dans le buffer de données résiduelles.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En fait, tu devrais pouvoir t'inspirer de la fonction linux getline(), pour la gestion de ton buffer et de sa taille :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int my_getline(char **pp, int *pTaille, int fd)
    {
    	/*Gérer l'allocation du buffer et son agrandissement dans une boucle*/
    }
     
    char* get_next_line(int fd)
    {
    	static char* buffer;
    	static int taille;
    	my_getline(&buffer, &taille, fd);
    	return buffer;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre confirmé Avatar de awesomeman
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 166
    Par défaut
    Oui j'avais pensé à faire ca justement ,c'est peut etre idiot mais je vois pas comment agrandir le buffer.
    pour la boucle ca donne un truc du genre?
    cmp étant la variable qui me permet de me déplacer dans mon buffer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(READ_SIZE <= cmp)
        {
        buff[READ_SIZE] += 1;
        }

  8. #8
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    C'est une boucle de lecture de fichier, tu dois donc avoir un appel à read à l'intérieur. Pose ton algo sur papier pour que ce soit moins confus, tu gagneras du temps.


    L'agrandissement du buffer consiste à déplacer les informations vers un nouvel emplacement. C'est une simple opération de type realloc : allocation, copie, libération.


    Enfin, Je ne suis pas partisan du static char* buffer; /* ... */ return buffer; de Médinoc, car :
    • il faut définir un protocole pour libérer cette zone mémoire plus tard, ce sera crade et/ou peu robuste (appel de la fonction avec un descripteur nul pour lui signaler de réinitialiser buffer ? renvoi d'un char ** et décharge de cette responsabilité sur l'appelant ? pas glop ) ;
    • l'appelant ne doit pas modifier le contenu du résultat (qui n'est d'ailleurs pas labellisé const) car celui-ci contient les informations résiduelles vitales pour que les appels suivants fonctionnent ;
    • il faut insérer manuellement un '\0' après le '\n' pour délimiter le résultat. En effet get_next_line n'informe pas l'appelant du nombre d'octets parcourus à la fgets. C'est d'ailleurs selon moi - hors du contexte d'un simple exercice - une très mauvaise idée.

    Ta déclaration de tableau en statique était bien préférable à mon sens. De toute façon ce tampon ne sert que pour une opération de lecture à la fois, il n'est pas sensé changer de taille tant que READ_SIZE ne devient pas un paramètre dynamique.

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/04/2014, 12h14
  2. [DOM] Lire ce qu’affiche une fonction javascript plutôt que le script
    Par MaxJenius dans le forum Général JavaScript
    Réponses: 15
    Dernier message: 29/04/2008, 18h15
  3. Commande DEL dans la fonction Shell
    Par Safaritn dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 12/01/2008, 23h48
  4. lire la sortie d'une fonction linux
    Par NexRezzo dans le forum C
    Réponses: 2
    Dernier message: 02/12/2007, 01h08
  5. Lire le mot dans une fonction
    Par paterson dans le forum C
    Réponses: 8
    Dernier message: 10/03/2007, 10h47

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