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 :

Get Next Line - Problème de compréhension


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Femme Profil pro
    Epitech
    Inscrit en
    Décembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Décembre 2017
    Messages : 5
    Par défaut Get Next Line - Problème de compréhension
    Bonsoir tout le monde!

    Je suis venue avec une version de Get Next Line que j'aimerais comprendre
    Voici le gnl.c:

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include "get_next_line.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
     
    int		stock(char **overflow, char **line, int *compteur)
    {
    	int		i;
    	char	*save;
     
    	i = 0;
    	while ((*overflow)[i])
    		if ((*overflow)[i] == '\n')
    		{
    			save = memalloc((strlen(*overflow) - i) * sizeof(char));
    			if (!save)
    				return (-1);
    			save = strcpy(save, &((*overflow)[i + 1]));
    			*line = strncpy(*line, *overflow, i);
    			(*line)[i++] = '\0';
    			free(*overflow);
    			*overflow = save;
    			return (1);
    		}
    		else
    			i++;
    	*compteur += i;
    	*line = strncpy(*line, *overflow, i);
    	*line = (char *)realloc(*line, *compteur, *compteur + BUFF_SIZE + 1);
    	free(*overflow);
    	*overflow = NULL;
    	return (0);
    }
     
    int		line_split(char **overflow, char **line, int *compteur)
    {
    	int	i;
     
    	(*line)[*compteur] = '\0';
    	i = 0;
    	while ((*line)[i])
    	{
    		if ((*line)[i] == '\n')
    		{
    			if ((*line)[i + 1])
    			{
    				*overflow = (char *)memalloc((*compteur - i) * sizeof(char));
    				if (!*overflow)
    					return (-1);
    				*overflow = strncpy(*overflow, (*line + i + 1), *compteur - i);
    				(*overflow)[*compteur - i - 1] = '\0';
    			}
    			(*line)[i] = '\0';
    			return (1);
    		}
    		i++;
    	}
    	return (0);
    }
     
    int		initialisation(const int fd, char ***line, char ***overflow)
    {
    	if (fd < 0 || fd > 5000 || !*line || FDS <= 0 || BUFF_SIZE <= 0)
    		return (-1);
    	if (!*overflow)
    	{
    		if (!(*overflow = (char **)memalloc(FDS * sizeof(char *))))
    			return (-1);
    	}
    	if (!(**line = (char *)memalloc((BUFF_SIZE + 1) * sizeof(char))))
    	{
    		free(*overflow);
    		return (-1);
    	}
    	return (0);
    }
     
    int		get_next_line(const int fd, char **line)
    {
    	static	char	**overflow;
    	int				r;
    	int				compteur;
    	int				resultat;
     
    	compteur = 0;
    	if (initialisation(fd, &line, &overflow))
    		return (-1);
    	if (overflow[fd] && (resultat = stock(&(overflow[fd]), line, &compteur)))
    		return (resultat);
    	while ((r = read(fd, (*line + compteur), BUFF_SIZE)) > 0 && (compteur += r))
    		if ((resultat = line_split(&(overflow[fd]), line, &compteur)))
    			return (resultat);
    		else if (r == BUFF_SIZE)
    		{
    			*line = (char *)realloc(*line, compteur * sizeof(char),
    					(compteur + BUFF_SIZE + 1) * sizeof(char));
    			if (!*line)
    				return (-1);
    		}
    	if (r < 0 || ((*line)[compteur] = '\0'))
    		return (-1);
    	return (**line ? 1 : 0);
    }
    Voici le gnl.h:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifndef GET_NEXT_LINE_H
    # define GET_NEXT_LINE_H
    # include <strings.h>
    # define BUFF_SIZE 1
    # define FDS 3000
     
    int				get_next_line(const int fd, char **line);
     
    #endif
    Voici le main.c que j'ai réussi à faire:

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include "get_next_line.h"
    #include <string.h>
     
    int		main(int argc, char **argv)
    {
    	int		fd;
    	char	*line;
    	int		i;
    	int		ret;
     
    	i = 0;
    	(void)argc;
    	fd = open((argv[1]), O_RDONLY);
    	while (i < 120)
    	{
    		line = (char *)malloc(sizeof(*line) * 1);
    		ret = get_next_line(fd, &line);
    		printf("--|%s\n", line);
    		i++;
    	}
    }
    Le problème est que je n'arrive pas à comprendre comment fonctionnent les fonctions du fichier gnl.c. Je sais quelle fonction fait quoi grâce aux noms de chaque fonction qui est assez explicite (Je suis assez débrouillarde.), mais je ne comprends pas ce qu'elle fait en détail.
    Puis, je n'ai toujours pas réussi à assimiler la méthode du BUFF_SIZE comment un programme se sert de la mémoire.
    Donc si certaines personnes ont du temps à me consacrer et à me supporter, je suis preneuse!

    Merci!

    - Julia

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 769
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 769
    Par défaut
    Citation Envoyé par PrettyLittleLiars Voir le message
    Voici le main.c que j'ai réussi à faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	line = (char *)malloc(sizeof(*line) * 1);
    Donc tu as fais le main et tu viens d'Epitech.
    Bien ce n'est pas brillant
    1. aucun free
    2. aucun free en sachant 1 malloc par tour de boucle
    3. sizeof c'est avec un type
    4. sizeof avec une variable d'accord (mais je me méfierai du compilateur C que tu utilises), mais c'est un char (sizeof(char) == 1)

  3. #3
    Membre à l'essai
    Femme Profil pro
    Epitech
    Inscrit en
    Décembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Décembre 2017
    Messages : 5
    Par défaut
    Me revoilà avec une version améliorée du main:

    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
    int		main(int argc, char **argv)
    {
    	int		fd;
    	char	*line;
     
    	if (argc == 1)
    		fd = 0;
    	else if (argc == 2)
    		fd = open(argv[1], O_RDONLY);
    	else
    		return (2);
    	while (get_next_line(fd, &line) == 1)
    	{
    		putendl(line);
    		free(line);
    	}
    	if (argc == 2)
    		close(fd);
    }
    Le main n'étant pas le problème principal de ce topic, je l'ai quand même repris de zéro avec un peu plus de logique (pour le perfectionnement personnel) et une meilleure gestion de la mémoire (enfin, je pense).
    Merci en tout cas de le notifier, foetus!

    Citation Envoyé par PrettyLittleLiars Voir le message
    Le problème est que je n'arrive pas à comprendre comment fonctionnent les fonctions du fichier gnl.c.

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Nous aurions besoin d'un peu plus d'info à propos du contexte.

    D'où est-ce que vient ce code ? Il y a plusieurs points suspects : overengineering, utilisation de strncpy en lieu et place de memcpy, cast de la valeur de retour des fonctions d'allocation dynamique, par ailleurs sur-utilisées selon moi, etc..

    Pourrait-on également connaître la spécification de ce get_next_line ? Autrement dit, avant de t'aider à comprendre comment la fonction fait ce qu'elle fait, pourrait-on savoir ce qu'elle est sensée faire ? Quelles en sont les pré- et post-conditions ? J'imagine que l'exercice est accompagné d'un énoncé (quoique, connaissant les fabriques à robots comme Epitech..).

  5. #5
    Membre à l'essai
    Femme Profil pro
    Epitech
    Inscrit en
    Décembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Décembre 2017
    Messages : 5
    Par défaut
    Oui, bien sur Matt_Houston, au temps pour moi!

    Ecrivez une fonction qui retourne une ligne lue depuis un file descriptor.
    Votre fonction aura le prototype suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int get_next_line(const int fd, char **line);
    Le premier paramètre est le file descriptor depuis lequel lire.
    • Le second paramètre est l’adresse d’un pointeur sur caractère qui servira à stocker
    la ligne lue sur le file descriptor.
    • La valeur de retour peut être 1, 0 ou -1 selon qu’une ligne a été lue, que la lecture
    est terminée ou bien qu’une erreur est survenue respectivement.
    • Votre fonction get_next_line doit renvoyer son resultat sans le ’\n’.
    • Un appel en boucle à votre fonction get_next_line permettra donc de lire le
    texte disponible sur un descripteur de fichier une ligne à la fois jusqu’à la fin du
    texte, quelque soit la taille du texte en question ou d’une de ses lignes.
    • Assurez-vous que votre fonction se comporte bien lorsqu’elle lit depuis un fichier,
    depuis l’entrée standard, depuis une redirection, etc.
    • Les variables globales sont interdites.
    • Les variables statiques sont autorisées.

    Si je fais des casts, c'est pour compacter les fonctions qui doivent faire 25 lignes maximum. On a pris pour habitude d'en faire à l'école.
    Je ne connais pas le terme overengineering, mais si vous voyez toutes ces fonctions, c'est parce qu'on a été amenés à inventer notre librairie de fonctions autorisées par l'école.

    Merci de m'aider en tout cas, et désolée de ne pas avoir amené ces consignes dès le début. ^^

    - Julia

  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
    Si je fais des casts, c'est pour compacter les fonctions qui doivent faire 25 lignes maximum
    Ça n'a absolument rien à voir!

    Edit: Au passage, ce n'est pas la première fois que get_next_line() (et les problèmes de son prototype imposé qui la rendent inférieure à getline()) est discuté sur ce forum.
    Voir ici par exemple (notamment les fonctions append_char et get_next_line)
    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.

Discussions similaires

  1. [Débutant] problème de compréhension
    Par Sylvester dans le forum Général Java
    Réponses: 18
    Dernier message: 21/07/2005, 09h16
  2. Réponses: 5
    Dernier message: 11/04/2005, 10h21
  3. [C#] Problème de compréhension de System.Convert ET Provider
    Par papouAlain dans le forum Windows Forms
    Réponses: 5
    Dernier message: 18/11/2004, 21h52
  4. onclipevent (problème de compréhension)
    Par stephane eyskens dans le forum Flash
    Réponses: 8
    Dernier message: 24/09/2003, 15h09
  5. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07

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