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

  1. #1
    Membre habitué 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
    Points : 136
    Points
    136
    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
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    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 habitué 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
    Points : 136
    Points
    136
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    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
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    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 habitué 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
    Points : 136
    Points
    136
    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
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    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.
    1. Je n'aime pas non plus, mais je suis parti du principe que ce prototype était exigé par l'énoncé.
    2. Quelles informations résiduelles vitales? Si la fonction est bien faite, à la fin de get_next_line(), tout ce que le buffer contient, c'est la ligne en question (si on utilise un buffer de lecture dans le fichier, celui-ci ne devra pas être retourné par get_next_line()).
    3. Pour moi c'est à get_next_line() de le faire (sauf que je remplacerais le \n au lieu de le retourner, mais c'est un goût personnel).
    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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    En fait, autant poser carrément la question: awesomeman, le prototype char* get_next_line(const int fd) t'est-il imposé?
    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.

  11. #11
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Oui laissons-le clarifier cela mais je pense bien que ça lui est imposé, d'où la contrainte static sur le tampon inutile autrement.

    Je n'avais pas compris que tu déléguais la sauvegarde du contexte à my_getline, ok dans ce cas mais je ne vois pas trop l'intérêt du wrapper. Passer par my_getline ne permettra pas d'en éliminer les défauts, comme l'impossibilité de différencier un cas d'erreur d'une fin de fichier.

    Citation Envoyé par Médinoc Voir le message
    Pour moi c'est à get_next_line() de le faire (sauf que je remplacerais le \n au lieu de le retourner, mais c'est un goût personnel).
    En fait, si ta stratégie est de remplacer le caractère, peu importe. Si le '\n' doit être conservé, alors puisque la fonction qui prend en charge l'allocation mémoire doit prévoir un byte pour '\0', autant que ce soit sa responsabilité.

  12. #12
    Membre habitué 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
    Points : 136
    Points
    136
    Par défaut
    Oui le proto est imposé

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    l'impossibilité de différencier un cas d'erreur d'une fin de fichier.
    J'ai l'impression que c'est un problème inhérent aux descripteurs POSIX, où il semble manquer une fonction équivalent à feof(). Apparemment, sous POSIX la fin de fichier c'est "read() retourne zéro".

    Le gros problème, c'est que le prototype imposé est voué à poser des problèmes, car il empêche de gérer de façon efficace un contexte qui soit spécifique au descripteur de fichier (comme un buffer de lecture): Le seule moyen serait de gérer, en variable statique/globale/globale-déguisée, une liste associant un contexte à chaque descripteur.

    Par contre, puisqu'on est réduit à lire les octets un par un, on peut régler un champ de contexte qui dit "la dernière lecture a rencontré EOF", et fournir une fonction qui le consulte (mais ça oblige à externaliser le contexte dans une fonction autre que get_next_line(); on aura donc une fonction du genre struct getnextlinecontext* get_getnextline_context() et la structure pourra contenir le pointeur du buffer de ligne et sa taille, ainsi que le flag "EOF en dernière lecture" (pas de buffer de lecture par contre, dû à son affinité au descripteur)).
    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.

  14. #14
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    J'ai l'impression que c'est un problème inhérent aux descripteurs POSIX, où il semble manquer une fonction équivalent à feof(). Apparemment, sous POSIX la fin de fichier c'est "read() retourne zéro".
    Pour moi c'est très clair : 0 pour EOF, -1 plus errno pour erreur. Le souci provient du prototype de cet exercice qui renvoie une chaîne, forcément null-terminated.


    Citation Envoyé par Médinoc Voir le message
    Le gros problème, c'est que le prototype imposé est voué à poser des problèmes, car il empêche de gérer de façon efficace un contexte qui soit spécifique au descripteur de fichier (comme un buffer de lecture): Le seule moyen serait de gérer, en variable statique/globale/globale-déguisée, une liste associant un contexte à chaque descripteur.

    Par contre, puisqu'on est réduit à lire les octets un par un, on peut régler un champ de contexte qui dit "la dernière lecture a rencontré EOF", et fournir une fonction qui le consulte (mais ça oblige à externaliser le contexte dans une fonction autre que get_next_line(); on aura donc une fonction du genre struct getnextlinecontext* get_getnextline_context() et la structure pourra contenir le pointeur du buffer de ligne et sa taille, ainsi que le flag "EOF en dernière lecture" (pas de buffer de lecture par contre, dû à son affinité au descripteur)).
    Je pense que tu te compliques la vie, le contenu de l'exercice est plutôt trivial : on a besoin d'un buffer de lecture persistant (argument de read) et d'un buffer de destination, non-persistant et régulièrement redimensionné en dynamique tant que la ligne en cours est incomplète.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    tant que non (EOF ou fin de ligne)
        si read_buf est vide alors
            lire au plus READ_SIZE octets dans read_buf
        soit n le nombre d'octets restants dans read_buf jusqu'à '\n'
        redimensionner dest_buf (+ 1 pour '\0')
        transférer les n premiers octets de read_buf vers dest_buf
    
    retourner dest_buf

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Je pense que tu te compliques la vie, le contenu de l'exercice est plutôt trivial : on a besoin d'un buffer de lecture persistant (argument de read) et d'un buffer de destination, non-persistant et régulièrement redimensionné en dynamique tant que la ligne en cours est incomplète.
    Et donc si je fais ceci, je casse tout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int fd = open( ... );
    char* ligne = get_next_ligne(fd);
    write(STDOUT_FILENO, "Ligne lue: ", 11);
    write(STDOUT_FILENO, ligne, strlen(ligne));
    write(STDOUT_FILENO, "\n(Question à l'utilisateur): ", 29);
    char *reponse = get_next_ligne(STDIN_FILENO); //Si ça ne pète pas dès ici...
    traiter(ligne, reponse);
    ligne =get_next_ligne(fd); //Alors ça pètera au moins là.
    On peut choisir d'oublier le buffer de lecture si le descripteur passé en paramètre change, mais sans se faire une table associative de buffers de lecture(!), on ne peut pas revenir à un descripteur qu'on a ainsi abandonné.

    Les deux seules solutions que je vois sont soit pas de buffer de lecture, soit une table associative (et tout le bookkeeping fastidieux qui va avec!)
    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.

  16. #16
    Membre habitué 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
    Points : 136
    Points
    136
    Par défaut
    oula tu m'as perdu avec ton algo Matt, comment tu récupère ton n ?
    pas de problème pour le READ_SIZE mais les n caractères derrière celui ci nous sont inconnus , on ne peut pas connaitre n. tout ce qu'on sait sur la taille du texte passe par le buffer et son READ_SIZE.
    c'est vraiment la première fois que je me sens aussi bloqué ..
    Pourtant l'idée de la boucle ou on read est bonne mais j'ai tellement de choses qui me bloque (ex: que mettre dans la boucle).
    la j'arrive à afficher au delà du buffer (deux lignes en plus) mais c'est vraiment très sale et c'est plus du bricolage qu'autre chose.
    ah oui et en plus , ca m'affiche un stack smashing..

  17. #17
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Cela ne pètera pas, ça videra le buffer tranquillou avant d'entamer le nouveau descripteur.

    C'est pourri je te l'accorde, mais c'est ce qui est demandé. Je ne pense pas que l'équipe pédagogique du cours de prog système attende une gestion des collisions ici avec stratégie round-robin ou que sais-je.. On pourrait aussi réinitialiser get_next_line via un appel avec un identifiant de descripteur universellement invalide, ce ne serait pas non plus folichon.

  18. #18
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par awesomeman Voir le message
    oula tu m'as perdu avec ton algo Matt, comment tu récupère ton n ?
    pas de problème pour le READ_SIZE mais les n caractères derrière celui ci nous sont inconnus , on ne peut pas connaitre n. tout ce qu'on sait sur la taille du texte passe par le buffer et son READ_SIZE.
    c'est vraiment la première fois que je me sens aussi bloqué ..
    Relax, relis bien :
    Citation Envoyé par Matt_Houston Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        soit n le nombre d'octets restants dans read_buf jusqu'à '\n'
    Les octets restants dans le buffer de lecture, c'est-à-dire dans ce qui a été lu par le dernier appel à read. Pas dans le fichier/stream ! Bien entendu que tu ne sais pas combien il reste d'octets à lire.

    Mettons que tu doives lire ces trois lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A line.
     
    The next.
    Avec un READ_SIZE à 10, le premier system call (read) remplira le buffer avec : { 'A', ' ', 'l', 'i', 'n', 'e', '\n', '\n', 'T', 'h' }.

    Lors du premier appel, le n dont je cause vaut 7 et la fonction renvoie "A line\n".
    Lors du second appel, le n dont je cause vaut 1 et la fonction renvoie "\n", sans modifier le descripteur puisqu'il reste des informations dans le buffer de lecture.
    Lors du dernier appel, le n dont je cause vaut 2 (ce qu'il reste) et la fonction effectue un autre appel à read pour remplir le buffer à nouveau et compléter la ligne jusqu'à EOF.

  19. #19
    Membre habitué 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
    Points : 136
    Points
    136
    Par défaut
    ah oui désolé j'avais pas bien lu..
    ducoup tout va se passer dès qu'on va bloquer sur le \0 du buffer (qui se trouve après le h dans ton exemple ).
    à ce moment la je suppose que je dois read le reste et le stocker dans ma chaine à la suite des caractère précédent jusqu'à finir au \n .

  20. #20
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est cela : tu lis et ajoute les morceaux de ligne par blocs de taille au plus READ_SIZE dans ta chaîne de sortie.

    Il n'y a pas de '\0' dans le buffer car tu connais exactement sa taille : READ_SIZE. Ce n'est pas une chaîne mais un simple tableau de données brutes. Par rapport à la discussion plus haut au sujet du prototype, c'est d'ailleurs un autre mauvais point au fait de renvoyer un null-terminated char * : get_next_line est incapable de prendre en compte les caractères nuls au sein d'un fichier texte.

    La fonction de bibliothèque fgets a le même défaut.

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