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 :

Petit probleme avec retour de pointeur d'une fonction


Sujet :

C

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    502
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 502
    Points : 227
    Points
    227
    Par défaut Petit probleme avec retour de pointeur d'une fonction
    salut,

    j'ai crée un fichier source :A.c

    voici la fonction :

    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
     
    char * choixPersonnage(void)
    {
    char * g ="Guerrier";
    char * m="Magicien";
    char * r;
     
    int choix;
     
    do{
    printf("choisisez un heros:\n");
    scanf("%d",&choix);
     
    switch(choix)
    {
    case 1 : r=g; break;
    case 2 : r=m;break;
    default :printf("veuillez recomencer votre choix\n");
    }
    }while (choix!=1&&choix!=2);
     
    return r;
    }
    le probleme est quand j'introduit la fonction dans le programme principal


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    int main()
    {
    char * p;
     
    p=choixPersonnage();
     
    printf("%s",*p);
     
    return 0;
    }

    j'ai une erreur :1)pourquoi ?


    2) toujours avec les pointeur lors d'un fonction
    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void affiche (char *s)
    {
    if (s=="magicien")
    {
    printf("vous etes un magicien");
    }
    else
      {
    printf("vous etes un guerrier\n");
     }
    }
    a (s=="magicien") pourquoi faut t'il ecrire s et non *s==magicien

    merci !

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Parce que *s, c'est un bète char.

    Mais le == ne marchera pas non plus. Pour comparer deux chaînes, il faut utiliser la fonction strcmp(), déclarée dans <string.h>.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    En C, les chaînes de caractères ne se comparent pas de cette façons !
    Une chaîne de caractère est avant tout une série de plusieurs valeur de type char se terminant par la valeur '\0'. faire donc (s == "chaine") ou (*s == "chaine) n'a aucun sens...

    Il faut utiliser la fonction strcmp() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int ret = strcmp(s, "Guerrier");
    if(ret == 0)
    {
        // les deux chaînes sont identiques
    }
    else if(ret < 0)
    {
        // s est alphabétiquement plus petite que "Guerrier"
    }
    else if(ret > 0)
    {
        // s est alphabétiquement plus grande que "Guerrier"
    }
    Il n'y a pas d'autres moyens de comparer, à moins de faire la comparaison toi-même, mais ça sera la même chose, il faut comparer chaque caractère des deux chaînes un à un...

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Asmod_D Voir le message
    j'ai crée un fichier source :A.c

    voici la fonction :
    <...>
    le probleme est quand j'introduit la fonction dans le programme principal
    <...>
    j'ai une erreur :1)pourquoi ?
    Parce que le code est incomplet. Un compilateur bien réglé ne s'y trompe pas
    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
     
    Project   : Forums
    Compiler  : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: fclean.c
    Compiling: main.c
    main.c:4: warning: function declaration isn't a prototype
    main.c: In function `main':
    main.c:7: warning: implicit declaration of function `choixPersonnage'
    main.c:7: warning: assignment makes pointer from integer without a cast
    main.c:9: warning: format argument is not a pointer (arg 2)
    Compiling: a.c
    a.c: In function `choixPersonnage':
    a.c:3: warning: initialization discards qualifiers from pointer target type
    a.c:4: warning: initialization discards qualifiers from pointer target type
    a.c:10: warning: implicit declaration of function `printf'
    a.c:11: warning: implicit declaration of function `scanf'
    a.c:5: warning: 'r' might be used uninitialized in this function
    Linking console executable: console.exe
    Process terminated with status 0 (0 minutes, 1 seconds)
    0 errors, 9 warnings
    Tu appelles une fonction sans prototype. Le C considère que le type par défaut est int, alors qu'il est char *, d'où le conflit.

    Tu devrais relire les principes de la programmation séparée (ou modulaire) dans ton livre de C.

    Rappel :

    Quand on crée un fichier séparé ("a.c", préfère les minuscules, c'est plus clair) qui contient l'implémentation de certaines fonctions, il faut aussi créer un fichier "a.h" qui contient l'interface de ces fonctions, c'est à dire les prototypes des fonctions publiques de a.c et tout ce qui est nécessaire pour définir ces prototypes. Ce fichier est protégé contre les inclusions multiples par un mécanisme de ce type (l'identificateur doit être le plus unique possible) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* a.h */
    #ifndef H_A_20080104
    #define H_A_20080104
     
    /* prototypes etc. */
     
    #endif
    Ce fichier a.h appelé interface ou header ou en-tête est en suite inclus
    En premier dans a.c (très important pour vérifier que le header est bien autonome et qu'il y a cohérence entre l'interface et l'implémentation).
    Dans chaque fichier qui utilise les fonctions de a.c (ici, main.c, par exemple).

    Je te laisse faire les modifications qui s'imposent.

    Détails et compléments :

    http://emmanuel-delahaye.developpez.com/codage.htm

    A par ça, il y a pas mal de bugs dans le code. Le compilateur devrait te guider. Par contre, l'usage de scanf() est incorrect et en cas d'erreur, de saisie, c'est le drame...

    Je déconseille l'usage de scanf() (complexe) au profit de l'usage exclusif de fgets() pour toutes les saisies, suivie de la fonction de nettoyage fclean() (fonction 'communautaire' dont on trouve le code source sur ce forum, poser des questions si besoin est) quitte à utiliser ensuite une fonction de conversion si nécessaire (sscanf(), strtol() etc.)

  5. #5
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Asmod_D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char * p;
    ...
    printf("%s",*p);
    C'est p ou *p que tu veux afficher?
    Citation Envoyé par Asmod_D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    int main()
    {
        char * p;
     
        p = choixPersonnage();
     
        printf("%s",*p);
     
        return 0;
    }
    Pas de déclaration de choixPersonnage avant son utilisation ...
    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>
     
    char * choixPersonnage(void);
     
    int main()
    {
        char * p;
     
        p = choixPersonnage();
     
        printf("%s",*p);
     
        return 0;
    }
    Citation Envoyé par Asmod_D
    Pour comparer deux chaînes on les compare caractère par caractère, pas en comparant leur adresse. Il y a une fonction pour faire ça : strcmp, déclarée dans string.h.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (strcmp(s, "magicien") == 0)

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    502
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 502
    Points : 227
    Points
    227
    Par défaut
    merci pour toutes vos reponses.


    merci pour la comparaison avec strcmp()

    mais je voudrais savoir comment avec une fonction renvoyant un pointeur de type char

    exemple :mon code choixPersonnage

    puis je prendre la valeur du retour afin de l'afficher





    merci !

  7. #7
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Qu'est-ce qui peut t'empêcher de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
     
    char * choixPersonnage(void);
     
    int main()
    {
        printf("%s", choixPersonnage());
        return 0;
    }
    ?

    Ou encore :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    if (strcmp(choixPersonnage(), "magicien") == 0)
        ...

  8. #8
    Futur Membre du Club
    Inscrit en
    Février 2004
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par Asmod_D Voir le message
    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
     
    char * choixPersonnage(void)
    {
    char * g ="Guerrier";
    char * m="Magicien";
    char * r;
     
    int choix;
     
    do{
    printf("choisisez un heros:\n");
    scanf("%d",&choix);
     
    switch(choix)
    {
    case 1 : r=g; break;
    case 2 : r=m;break;
    default :printf("veuillez recomencer votre choix\n");
    }
    }while (choix!=1&&choix!=2);
     
    return r;
    }
    J'espere ne pas dire de bêtise, mais l'espace mémoire pointé par g et m est alloué statiquement dans ta fonction. Il n'existe donc plus en sortie de ta fonction. Il est donc necessaire d'allouer dynamiquement l'espace associé à r si tu veux continuer de l'utiliser en dehors (pour l'afficher notamment), et pas simplement le faire pointer sur celles correspondantes à g ou m.
    Regarde du côté de strdup().

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Ben si, tu dis une bêtise.
    Les pointeurs g et m eux-mêmes sont en mémoire automatique, mais les données pointées sont en mémoire statique.

    Par contre, ces pointeurs, ainsi que le type de retour, seraient mieux en const char *.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Non, mcyrb, là ça n'a aucun intérêt de faire ça, la mémoire serait occupé par plusieurs fois la même chaîne de caractères. Il vaut mieux soit en faire une chaîne constante globale ou alors carrément une constante numérique, via un enum par exemple, ce qui serait beaucoup plus propre que de chaque fois faire la comparaison de la chaîne de type du personnage...

  11. #11
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par mcyrb Voir le message
    J'espere ne pas dire de bêtise, mais l'espace mémoire pointé par g et m est alloué statiquement dans ta fonction. Il n'existe donc plus en sortie de ta fonction. Il est donc necessaire d'allouer dynamiquement l'espace associé à r si tu veux continuer de l'utiliser en dehors (pour l'afficher notamment), et pas simplement le faire pointer sur celles correspondantes à g ou m.
    Regarde du côté de strdup().
    Cette discussion pourrait t'interesser (à partir du post 36).

  12. #12
    Futur Membre du Club
    Inscrit en
    Février 2004
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Ah oui en effet au temps pour moi
    Merci pour ces précisions.

Discussions similaires

  1. Réponses: 4
    Dernier message: 22/11/2009, 23h35
  2. retour de pointeur par une fonction
    Par Miko95 dans le forum C++
    Réponses: 17
    Dernier message: 12/12/2007, 01h33
  3. petit probleme avec une liste chainée
    Par kamouminator dans le forum C
    Réponses: 26
    Dernier message: 06/11/2006, 20h18
  4. Petit probleme avec les Border lors d'une sauvegarde
    Par Mike888 dans le forum Interfaces Graphiques en Java
    Réponses: 7
    Dernier message: 06/06/2006, 09h33
  5. Réponses: 7
    Dernier message: 20/03/2006, 12h19

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