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 :

gestion de signets(allocation dynamique de la mémoire)


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    120
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 120
    Par défaut gestion de signets(allocation dynamique de la mémoire)
    Bonsoir,
    voila le but de l'exercice est la gestion de signet en utilisant l'alocation dynamique de la mémoire.
    chacun des signets sauvegardés contient l'url du signet, une description du site ainsi qu'un nombre d'étoiles pour ce site (allant de 0 à 5).
    je doit créer un signet et l'afficher !
    J'ai beaucoup de difficulté concernant ce chapitre étant donné que je ne l'est abordé uniquement en cour donc j'ai consulté le tutoriel de ce site mais j'ai encore du mal
    pourquoi mon programme ne fonctionne t'il pas et si je n'est pas comprit quelque point sur ce chapitre me les expliquer briévement.
    Je vous remercie d'avance...

    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
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    struct signet{
      char *url;
      char *description;
      int etoile;
    }
     
    void creation(char *url,char *description,int etoile){
      struct signet *s
      s=(struct signet *) malloc (sizeof(struct signet));
      s->url=(char *) calloc(strlen(url)+1,sizeof(char));
      strcpy(s->url);
      s->=(char *) calloc(strlen(description)+1,sizeof(char));
      strcpy(s->description,description);
      s->etoile=etoile;
    }   
     
    void affiche(struct signet *s){
      printf("url:%s\n",s->url);
      printf("description:%s\n",s->description);
      printf("qualité du site: %d\n",s->etoile);
    } 
     
    int main(){
      char url[1]={"url@fournisseur.com"};
      char description[1]={"site complet"};
      int etoile=3;
      creation(&url,&description,etoile);
      affiche(s);
      return 0;
    }

  2. #2
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    j'ai corrigé un peu ton code, pose des questions sur ce qui n'est pas clair
    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
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    /* la déclaration termine par un ; */
    struct signet{
      char *url;
      char *description;
      int etoile;
    };
     
     
    struct signet * creation(char *url,char *description,int etoile){
      struct signet *s;
      s=malloc(sizeof*s); /* transtypage inutile, simplification de l'écriture en allouant la taille de l'objet qui est pointé */
      if(s!=NULL){
          s->url=calloc(strlen(url)+1,sizeof(char));
          strcpy(s->url,url);
          s->description=calloc(strlen(description)+1,sizeof(char));
          strcpy(s->description,description);
          s->etoile=etoile;
      }
      return s;
    }
     
    void affiche(struct signet *s){
      printf("url:%s\n",s->url);
      printf("description:%s\n",s->description);
      printf("qualité du site: %d\n",s->etoile);
    }
     
    int main(){
        /* pour l'initialisation à la déclaration tu n'es pas obligé de préciser la taille et 1 est trop court */
      char url[]={"url@fournisseur.com"};
      char description[]={"site complet"};
      int etoile=3;
      struct signet *s = creation(url,description,etoile);
      if(s!=NULL) {
        affiche(s);
        free(s);
      }
      return 0;
    }

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    120
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 120
    Par défaut
    Merci beaucoup pour l'aide est les explications, il y a juste une chose que je n'est pas bien comprit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct signet *s = creation(url,description,etoile);
    cela permet de modifier les données de la structure signet?

  4. #4
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Citation Envoyé par Delnir Voir le message
    Merci beaucoup pour l'aide est les explications, il y a juste une chose que je n'est pas bien comprit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct signet *s = creation(url,description,etoile);
    cela permet de modifier les données de la structure signet?
    tu as besoin d'une variable signet, la fonction creation s'occupe de la construire à partir des paramètres que tu lui donnes et te renvoi un pointeur dessus. si la création se passe bien (s!=NULL) s est une adresse valide sur une zone contenant une variable de type signet

    il faut par contre que tu te charges de la destruction, destruction(s); qui libérera les différentes appels à malloc+calloc

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    120
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 120
    Par défaut
    voila j'ai refait l'exercice mais la en créant directement avec une fonction les signets, mais sa ne fonctione pas je comprend pas trop pourquoi :/
    je parie que c'est encore cette foutu fonction scanf qui fait tout déconner
    qu'est ce qui ne marche pas? et comment puis-je faire pour garder la valeur d'une variable d'une fonction pour pouvoir l'utiliser dans une autre? (ici j'en est besoin pour savoir le nombre d'élément que l'utilisateur va entrer afin de l'afficher)
    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
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    struct signet{
      char *url;
      char *description;
      int etoile;
    };
     
     
    struct signet *creesignet(struct signet *s){
      int i,x;
      char stop;
      char *url,*description;
      stop='O';
      x=0;
      i=0;
      s=malloc(sizeof(s));
      if (s!=NULL){
        while (stop=='O'){
          if (x>0) s=realloc(s,sizeof(s)*(x+1));
          printf("donnez l'url:\n");
          scanf("%s",url);
          while ((i=getchar())!='\n'&& i!=EOF);
          (s+x)->url=calloc(strlen(url)+1,sizeof(char));
          strcpy(s->url,url);
          printf("donnez la description:\n");
          scanf("%s",description);
          while ((i=getchar())!='\n'&& i!=EOF);
          (s+x)->description=calloc(strlen(description)+1,sizeof(char));
          strcpy((s+x)->description,url);
          printf("donnez une note de 1 à 5: \n");
          scanf("%d",&((s+x)->etoile));
          while ((i=getchar())!='\n'&& i!=EOF);
          printf("souhaiter vous continuer\n");
          scanf("O/N: oui/non %c",&stop);
          x++;
        }
      }
      else printf("erreur");
      return s;
    }
     
    void affiche(struct signet *s){
      int i;
      for (i=0;i<3;i++){
        printf("url:%s\n",(s+i)->url);
        printf("description:%s\n",(s+i)->description);
        printf("qualité du site: %d\n",(s+i)->etoile);
      }
    }
     
     
     
     
     
     
     
    int main(){
      int i;
      struct signet *s;
      if (s!=NULL){
        struct signet *s=creesignet(s);
        for (i=0;i<3;i++){
          free((s+i)->url);
          free((s+i)->description);
          free(&((s+i)->etoile));
          free(s+i);
        }
      }
      else printf("erreur");
      return 0;
    }

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    120
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 120
    Par défaut
    voila j'ai ajouter cette fonction permetant de modifier le 1er signet mais je ne suis pas sur de moi pour le realloc, est je bon?
    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
     
    struct signet *modifier(struct signet *s){
      char *url,*description;
      int i;
      printf("donnez l'url:");
      scanf("%s\n",url);
      while ((i=getchar())!='\n'&& i!=EOF);
      s->url=realloc(s->url,sizeof(char)*strlen(url)+1);
      strcpy(s->url,url);
      printf("donnez une description:");
      scanf("%s\n",description);
      while ((i=getchar())!='\n'&& i!=EOF);
      s->description=realloc(s->description,sizeof(char)*strlen(description)+1);
      strcpy(s->description,description);
      printf("donnez la note de 1 à 5:");
      scanf("%d\n",&(s->etoile));
      while ((i=getchar())!='\n'&& i!=EOF);
      return s;
    }

  7. #7
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Le code est faux, mais pas sur les realloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      char *url,*description;
    ...
      scanf("%s\n",url);
    ...
      scanf("%s\n",description);
    url et description sont des pointeurs donc des variables qui peuvent contenir des adresses. les scanf lisent une chaîne de caractères et il faut stocker ces chaînes dans des tableaux de char (suffisamment grands), donc passer ces tableaux en argument des scanf. Un pointeur ne peut stocker une chaîne de caractères.
    Revoir donc la définition de url et description

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      s->url=realloc(s->url,sizeof(char)*strlen(url)+1);
    ...
      s->description=realloc(s->description,sizeof(char)*strlen(description)+1);
    La réallocation peut échouer et dans ce cas realloc renvoie NULL. Avec l'écriture que tu utilises, l'adresse du bloc précédemment alloué est écrasée et on ne peut plus accéder à ce bloc qui est perdu dans la nature.
    Stocke le retour de realloc dans un pointeur intermédiaire. Si alors sa valeur est différente de NULL, la réallocation a réussi, et tu peux copier ce pointeur dans sa destination finale s->url ou s->description. Sinon, tu as toujours accès à l'ancien bloc pour prendre les dispositions prévues en cas d'échec.

Discussions similaires

  1. Réponses: 3
    Dernier message: 09/05/2012, 09h21
  2. Gestion des allocations dynamiques de mémoire.
    Par Franck.H dans le forum Télécharger
    Réponses: 0
    Dernier message: 30/11/2010, 17h24
  3. Gestion des erreurs, allocation dynamique
    Par mach1 dans le forum C
    Réponses: 11
    Dernier message: 02/05/2010, 19h19
  4. allocation dynamique de la mémoire
    Par ralf91 dans le forum C#
    Réponses: 4
    Dernier message: 08/04/2008, 18h16
  5. Réponses: 15
    Dernier message: 06/12/2006, 16h03

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