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 :

Fonctions,structures,lecture de fichier


Sujet :

C

  1. #21
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2013
    Messages : 13
    Points : 3
    Points
    3
    Par défaut
    Je comprends mieux merci

    Il me faudrait un exemple pour strcpy .. je comprend pas tant que j'ai pas d'exemple enfaite c'est trop complexe l'info ..

  2. #22
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    J'ai jamais compris comment faire appel a mes fonctions ..
    Je vais être direct : ouvre ton cours de C

    Comment ça ce fait qu'on a utiliser free sur nom et prenom et pas les autres champs ?
    Comme te l'a justement expliqué Bysbobo, un free() sert à libérer de la mémoire qui a été réclamée (ou encore réservée) explicitement. Une telle réservation se fait avec malloc(), calloc() ou realloc(). Si tu n'as pas utilisé une de ces fonctions sur ta variable, tu ne dois pas appeler free() dessus.

    En gros, toute allocation doit etre libérée par tes soins sinon sa peut planter.
    Ce n'est pas tant le risque de plantage qui est important. C'est surtout un problème de consommation mémoire inutile. Si tu fais une action toutes les minutes sans libérer la mémoire et que ton programme tourne pendant des mois, tu risques d'utiliser toute la mémoire de ton ordinateur (pour rien).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    est-il nécessaire d'utiliser strcpy ?
    Si tu veux copier une chaine dans une autre, oui. Exemple :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(void)
    {
        char source[100] = "bonjour";
        char dest[100] = {0};
     
        printf("Avant [%s][%s]\n", source, dest);
        strcpy(dest, source);
     
        printf("Apres [%s][%s]", source, dest);
        return 0;
    }
    Au passage, il doit y avoir des 10 aines d'exemple sur Google de l'utilisation de cette fonction. N'hésites pas aussi à regarder les ressources de Developpez, dans FAQ et Tutoriel. http://c.developpez.com/faq/?page=strings#STRINGS_init --> une entrée intéressante de la FAQ.

  3. #23
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2013
    Messages : 13
    Points : 3
    Points
    3
    Par défaut
    Merci pour ta réponse je vais faire un tour !.


    J'ai ensuite l'exercice 2.
    Dans cette exercice je dois créer des listes chaînées dont les maillons contiennent des fiche_t. On utilisera alors les fonctions de l'exercice 1.

    1. Définir la structure maillon_t qui contient un pointeur sur une fiche_t, nommé val, et un pointeur suiv vers un autre maillon_t.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct maillon_s{
        fiche_t  *val;
        maillon_t *suiv;
    };
    typedef maillon_s maillon_t;
    2. Ecrire la fonction maillon_creer qui prend en entrée un pointeur sur une fiche et renvoit un pointeur sur un maillon_t. Pensez à initialiser le champs suiv.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    maillon_t * maillon_creer(fiche_t *fiche)
    {
      maillon_t * res=(maillon_t*)malloc(sizeof(maillon_t));
      res->val = fiche;
      res->suiv = NULL;
      return res;
    }
    3. Ecrire la fonction maillon_detruire qui prend en entrée un pointeur sur un maillon_t, libère l'espace mémoire alloué dans la fonction maillon_creer et appel la fonction fiche_detruire (pas nécessairement dans cet ordre)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void maillon_detruire(maillon_t *m)
    {
      fiche_detruire(fiche_t *fiche);
      free(m->fiche);
      free(m);
    }
    4. Ecrire la fonction récursive maillon_affiche_rec qui prend en entrée un pointeur sur un maillon_t, affiche son contenu à l'aide de la fonction fiche_affiche, puis affiche le maillon suivant. Attention au test d'arrêt.

    Alors la je vois pas comment faire j'essaye un petit truc..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void maillon_affiche_rec (maillon_t *m)
    {
        printf("", m->val, m->fiche);
        m = m->suiv;
        maillon_affiche_rec(m);
     
    }
    5. Définir la structure liste_t qui contient un entier taille et un pointeur debut sur maillon_t.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct liste_s{
      int taille;
      maillon_t *debut;
    };
    typedef liste_s liste_t;
    6. Ecrire la fonction liste_creer qui ne prend rien en entrée et renvoie un pointeur sur une liste_t de taille 0.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void liste_creer()
    {
       liste_t *res = (liste_t*)malloc(sizeof(liste_t));
       res -> debut = NULL;
       res -> taille = 0;
       return res;
    }
    7. Ecrire la fonction liste_ajouter_debut qui prend en entrée un pointeur sur une liste_t et un pointeur sur une fiche_t et ajoute la fiche au début de la liste (ne pas oublier de modifier la taille de la liste)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void liste_ajouter_debut(liste_t *l, fiche_t *f)
    {
      if (liste_creer(*l) == NULL)
         l-> debut = NULL;
         l-> taille = 0;
      else
         l->debut = f;
         l-> taille ++;
    }

  4. #24
    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
    3. Attention, si fiche_detruire() fait un free() (comme elle devrait le faire), ta fonction maillon_detruire() va faire un double-free dessus, très mauvais. Tu devrais supprimer cet appel à free().
    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. #25
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    2) Vérifier que l'allocation s'est bien déroulée serait mieux.

    3) Qu'est censée faire cette ligne : fiche_detruire(fiche_t *fiche); ? Je ne peux qu'être d'accord avec Bktero.
    Que se passe-t-il aussi si je rentre un pointeur NULL dans cette fonction ?

    4) printf("", m->val, m->fiche); : Je ne vois aucun champ de ce nom dans ta structure.
    Je te laisse déboguer cette partie pour te rendre compte de quelque chose... et justement te relire

    6) Idem vérification de l'allocation.

    7) Tu as créé une fonction void liste_creer(), et utilises liste_creer(*l). Il y a comme un problème...
    Et je te conseille de revoir l'indentation de cette fonction. Le compilo saura te le rappeler

  6. #26
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2013
    Messages : 13
    Points : 3
    Points
    3
    Par défaut
    Donc ayant pris en compte vos reponses :

    1. Définir la structure maillon_t qui contient un pointeur sur une fiche_t, nommé val, et un pointeur suiv vers un autre maillon_t.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct maillon_s{
        fiche_t  *val;
        maillon_t *suiv;
    };
    typedef maillon_s maillon_t;
    2. Ecrire la fonction maillon_creer qui prend en entrée un pointeur sur une fiche et renvoit un pointeur sur un maillon_t. Pensez à initialiser le champs suiv.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    maillon_t * maillon_creer(fiche_t *fiche)
    {
      maillon_t * res=(maillon_t*)malloc(sizeof(maillon_t));
      if( res == NULL )
      {
         printf("allocation impossible");
       }
      res->val = val;
      res->suiv = NULL;
      return res;
    }
    3. Ecrire la fonction maillon_detruire qui prend en entrée un pointeur sur un maillon_t, libère l'espace mémoire alloué dans la fonction maillon_creer et appel la fonction fiche_detruire (pas nécessairement dans cet ordre)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void maillon_detruire(maillon_t *m)
    {
      free(m);
      fiche_detruire();
    }
    4. Ecrire la fonction récursive maillon_affiche_rec qui prend en entrée un pointeur sur un maillon_t, affiche son contenu à l'aide de la fonction fiche_affiche, puis affiche le maillon suivant. Attention au test d'arrêt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void maillon_affiche_rec (maillon_t *m)
    {
        printf("%d", m->val, m->suiv);
        m = m->suiv;
        maillon_affiche_rec(m);
    }
    5. Définir la structure liste_t qui contient un entier taille et un pointeur debut sur maillon_t.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct liste_s{
      int taille;
      maillon_t *debut;
    };
    typedef liste_s liste_t;
    6. Ecrire la fonction liste_creer qui ne prend rien en entrée et renvoie un pointeur sur une liste_t de taille 0.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void liste_creer()
    {
       liste_t *res = (liste_t*)malloc(sizeof(liste_t));
      if( res == NULL )
      {
         printf("allocation impossible");
       }
       res -> debut = NULL;
       res -> taille = 0;
       return res;
    }
    7. Ecrire la fonction liste_ajouter_debut qui prend en entrée un pointeur sur une liste_t et un pointeur sur une fiche_t et ajoute la fiche au début de la liste (ne pas oublier de modifier la taille de la liste)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void liste_ajouter_debut(liste_t *l, fiche_t *f)
    {
      if (liste_creer == NULL)
         l-> debut = NULL;
         l-> taille = 0;
      else
         l->debut = f;
         l-> taille ++;
    }

  7. #27
    Invité
    Invité(e)
    Par défaut
    2) et 6) Tes vérifications d'allocation sont à revoir...
    Que se passe t-il si elle échoue ? Tu affiches ton message et puis ?

    3) Quel est le rôle de la fonction fiche_detruire() ?

    4) As-tu regardé la documentation de la fonction printf() ? man printf
    Tu affiches le champ val avec %d, ok mais qu'en est-il du champ suiv ?

    4) et 7) Mêmes deuxièmes remarques que précédemment.

  8. #28
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2013
    Messages : 13
    Points : 3
    Points
    3
    Par défaut
    2 et 6. Enfaite pour l'allocation on n'a jamais vu ce que vous me demander les profs acceptent la fonction sans la vérification.

    Pour la fonction 3. On me demande de faire appel a la fonction fiche_detruire je ne sais pas donc j'ai tenter des choses stupides.

    Fonction 4 le champ suiv pointe vers un maillon donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d ,%p", m->val, m->suiv);

  9. #29
    Invité
    Invité(e)
    Par défaut
    Si les profs acceptent de faire du code non sécurisé...

    Il serait peut-être temps de réellement lire et comprendre un cours de C sur l'utilisation des fonctions et pointeurs histoire de faire des choses plus réfléchies ?

  10. #30
    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
    D'un autre côté, dans les cas d'école, une allocation mémoire n'échoue jamais. Donc on peut se permettre soit de ne pas gérer l'erreur, soit de la gérer avec un abort()...
    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. #31
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Je ne suis pas choqué qu'un programme scolaire (ou même un petit programme sans problème de robustesse) ne teste pas le retour des allocations dynamiques. Ne pas savoir qu'une allocation dynamique peut échouer est en revanche plus dommageable !

  12. #32
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Y'a que moi chez qui cette réponse choque?
    Citation Envoyé par Djiinw Voir le message
    4. Ecrire la fonction récursive maillon_affiche_rec qui prend en entrée un pointeur sur un maillon_t, affiche son contenu à l'aide de la fonction fiche_affiche, puis affiche le maillon suivant. Attention au test d'arrêt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void maillon_affiche_rec (maillon_t *m)
    {
        printf("%d", m->val, m->suiv);
        m = m->suiv;
        maillon_affiche_rec(m);
    }
    La fin de la question te dit de faire attention au test d'arrêt mais là tu tournes non stop non?
    Si tu ne mets pas de
    tu vas parcourir toute la mémoire possible sans t'arrêter...

Discussions similaires

  1. Fonction de lecture de fichier (variable)
    Par virtuadrack dans le forum C++
    Réponses: 2
    Dernier message: 23/01/2009, 20h17
  2. Lecture de fichiers .wav et fonction random
    Par Pedrozito dans le forum Interfaces Graphiques
    Réponses: 9
    Dernier message: 22/04/2008, 16h23
  3. Réponses: 5
    Dernier message: 26/03/2007, 01h30
  4. Fonction de lecture de fichier
    Par parisjohn dans le forum C
    Réponses: 6
    Dernier message: 24/11/2006, 14h29
  5. Réponses: 12
    Dernier message: 14/06/2004, 13h06

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