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 :

Pointeur de tableau


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 75
    Par défaut Pointeur de tableau
    Bonjour a tous (enfin plutôt bonne nuit )

    Voila, je suis en train de programmer un petit jeu, et je suis embetter par une fonction permettant de charger des informations.

    Je n'arrive pas a passer un pointeur de tableau d'une structure que j'ai crée.

    Voici la structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct Pnj Pnj;
    struct Pnj
    {
      char nom;
      int editeur; /*booléen indiquant si on est en mode jeu ou editeur
                     Si c'est éditeur, le pnj ne dois pas apparaitre*/
     
      int x; /*Position du pnj*/
      int y;
     
    };
    Voici ma fonction principale :

    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
    void lancementPartie(SDL_Surface *ecran, int mode)
    {
       /*Code*/
     
         Pnj pnj[5];
         Pnj *p_pnj[5]={NULL,NULL,NULL,NULL,NULL};
     
         for(i=0;i<5;i++)
         {
            p_pnj[i]=&pnj[i];
         }
     
         charger_pnj(p_pnj);
    /*Code*/
    }
    Voici le prototype de ma fonction charger_pnj :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void charger_pnj(Pnj *pnj[]);
    Et enfin voici ma fonction charger_pnj :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void charger_pnj(Pnj *pnj[])
    {
        FILE *fichier=fopen("pnj.txt","r");
        int i=0;
        if(fichier!=NULL)
        {
            for(i=0;i<5;i++)
            {
               fscanf(fichier,"%s %d %d %d",pnj[i]->nom,pnj[i]->x,pnj[i]->y,pnj[i]->editeur);
            }
        }
        fclose(fichier);
     
    }
    Mon compilo m'affiche ceci :

    fichier.c:324: warning: format argument is not a pointer (arg 3)
    fichier.c:324: warning: format argument is not a pointer (arg 4)
    fichier.c:324: warning: format argument is not a pointer (arg 5)
    fichier.c:324: warning: format argument is not a pointer (arg 6)
    :: === Génération finie: 0 erreurs, 4 avertissements ===
    Et lorsque je lance mon programme il plante.

    Merci d'avance

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 7
    Par défaut
    Ton erreur est lié a tes arguments dans ton appel a fscanf. Tu m'as tout l'air de passer les valeurs des éléments et non les adresses des éléments

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fscanf(fichier,"%s %d %d %d",pnj[i]->nom, pnj[i]->x, pnj[i]->y, pnj[i]->editeur);
    deviendrait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fscanf(fichier,"%s %d %d %d", pnj[i]->nom, &pnj[i]->x, &pnj[i]->y, &pnj[i]->editeur);
    Ca devrait regler le problème. Par contre, je sais pas comment est fait ton fichier pnj.txt mais fait attention avec la fonction fscanf, surtout que je vois que tu lis une chaine de caractere (ce qui peut etre dangereux si les données sont corrompus car scanf pourrait ecrire dans de la memoire qui n'appartient pas a la chaine de caractere). M'enfin, tu devrais peut-etre lire avec fgets ou sinon ajouter un gabarit maximum a ton code de formart %s.

    Ah et aussi, au lieu d'utiliser des "nombres magiques", comme 5, tu devrais definir une constante et utiliser cette constante la, ca reduit les risques d'erreurs et ca rend l'évolution/maintenance plus facile, tout en rendant le code plus facile a comprendre

    Et ici y est seulement 9h39 PM

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par lapos
    Mon compilo m'affiche ceci :
    <...>
    Et lorsque je lance mon programme il plante.
    Bah, oui. Il y a un tas d'erreurs et de complications inutiles... Ceci fonctionne :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    /* -ed- stub ... */
    typedef struct sdl_surface
    {
       int dummy;
    }
    SDL_Surface;
     
    typedef struct Pnj Pnj;
    struct Pnj
    {
       char nom[32];                /* -ed- pour une chaine, il faut de l'espace... */
       int editeur;                 /* booléen indiquant si on est en mode jeu ou
                                       editeur Si c'est éditeur,
                                       le pnj ne dois pas apparaitre */
       int x;                       /* Position du pnj */
       int y;
    };
     
    int charger_pnj (Pnj * pnj)
    {
       int err = 0; /* -ed- ajoute gestion d'erreur... */
       static char const fname[] = "pnj.txt";
       FILE *fichier = fopen (fname, "r");
       if (fichier != NULL)
       {
          int i;
          for (i = 0; !err && i < 5; i++)
          {
             int n =
                fscanf (fichier, "%31s %d %d %d", pnj[i].nom, &pnj[i].x,
                        &pnj[i].y,
                        &pnj[i].editeur);
             if (n != 4)
             {
                fprintf (stderr, "read error\n");
                err = 1;
             }
          }
          fclose (fichier);         /* -ed- etait mal place 
                                           (crash en cas d'erreur d'ouverture) */
       }
       else
       {
          err = 1;
          perror (fname);
       }
       return err;
    }
     
    void lancementPartie (SDL_Surface * ecran, int mode)
    {                               /*Code */
       Pnj pnj[5] = { {{0}} };
       int err = charger_pnj (pnj); /*Code */
     
       if (!err)
       {
          /* OK */
       }
       else
       {
          printf ("erreur de chargement\n");
       }
     
       /* -ed- parametres non utilises... */
       (void) ecran;
       (void) mode;
    }
     
    int main (void)
    {
     
       SDL_Surface ecran;
       int mode = 0;
       lancementPartie (&ecran, mode);
       return 0;
    }
    Pose des questions si tu ne comprends pas...

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 75
    Par défaut
    Ton erreur est lié a tes arguments dans ton appel a fscanf. Tu m'as tout l'air de passer les valeurs des éléments et non les adresses des éléments
    C'était bien ça.

    Ah et aussi, au lieu d'utiliser des "nombres magiques", comme 5, tu devrais definir une constante et utiliser cette constante la, ca reduit les risques d'erreurs et ca rend l'évolution/maintenance plus facile, tout en rendant le code plus facile a comprendre
    Je comptait le faire dès que cela aurais marché. Je les utilises régulièrement.

    Ca devrait regler le problème. Par contre, je sais pas comment est fait ton fichier pnj.txt mais fait attention avec la fonction fscanf, surtout que je vois que tu lis une chaine de caractere (ce qui peut etre dangereux si les données sont corrompus car scanf pourrait ecrire dans de la memoire qui n'appartient pas a la chaine de caractere). M'enfin, tu devrais peut-etre lire avec fgets ou sinon ajouter un gabarit maximum a ton code de formart %s.
    Et bien, je ne comprend pas trop. Vu que j'ouvre mon fichier en mode read, fscanf ne peut pas écrire et écraser mes données non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* -ed- stub ... */
    typedef struct sdl_surface
    {
       int dummy;
    }
    SDL_Surface;
    Je ne comprend pas du tout a quoi ce morceau de code sert.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char nom[32];                /* -ed- pour une chaine, il faut de l'espace... */
    Erreur stupide que j'ai vite rétablis.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static char const fname[] = "pnj.txt";
       FILE *fichier = fopen (fname, "r");
    Je ne comprend pas a quoi cela sert, pourquoi ne pas faire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *fichier = fopen ("pnj.txt", "r");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int n =
                fscanf (fichier, "%31s %d %d %d", pnj[i].nom, &pnj[i].x,
                        &pnj[i].y,
                        &pnj[i].editeur);
             if (n != 4)
             {
                fprintf (stderr, "read error\n");
                err = 1;
             }
    Je ne comprend pas à quoi sert la variable n. Apparement, si n n'est pas égale à 4 c'est une erreur, mais pourquoi n serais égale à 4 ? fscanf renvoie toujours la valeur 4 lorsqu'il c'est bien déroulé ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fclose (fichier);         /* -ed- etait mal place 
                                           (crash en cas d'erreur d'ouverture) */
    Je ne savais pas, je vais tout remplacer à ta façon.

    A quoi sert la fonction perror ? Je suppose que c'est pour prévenir qu'il y a eu une erreur mais je préfère etre sur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pnj pnj[5] = { {{0}} };
    Je ne comprend pas cette initialisation. Avec trois accolades, cela ne devrait il pas initialiser un tableau a trois dimension ?

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par lapos
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* -ed- stub ... */
    typedef struct sdl_surface
    {
       int dummy;
    }
    SDL_Surface;
    Je ne comprend pas du tout a quoi ce morceau de code sert.
    C'est un 'stub', c'est à dire une sorte de patch (rustine) qui permet de compiler, car le code posté est incomplet. Ca n'a pas de rôle fonctionnel. L'usage est de poster du code réduit mais complet.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static char const fname[] = "pnj.txt";
       FILE *fichier = fopen (fname, "r");
    Je ne comprend pas a quoi cela sert, pourquoi ne pas faire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *fichier = fopen ("pnj.txt", "r");
    Parce que je me sers 2 fois du nom du fichier...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int n =
                fscanf (fichier, "%31s %d %d %d", pnj[i].nom, &pnj[i].x,
                        &pnj[i].y,
                        &pnj[i].editeur);
             if (n != 4)
             {
                fprintf (stderr, "read error\n");
                err = 1;
             }
    Je ne comprend pas à quoi sert la variable n. Apparement, si n n'est pas égale à 4 c'est une erreur, mais pourquoi n serais égale à 4 ? fscanf renvoie toujours la valeur 4 lorsqu'il c'est bien déroulé ?
    Cette question est grave. Tu ne lis donc pas la doc des fonctions que tu utilises ?

    http://man.developpez.com/
    A quoi sert la fonction perror ? Je suppose que c'est pour prévenir qu'il y a eu une erreur mais je préfère etre sur.
    Quand tu découvres une fonction, le premier réflexe est de lire sa doc et non de poser une question basique ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pnj pnj[5] = { {{0}} };
    Je ne comprend pas cette initialisation. Avec trois accolades, cela ne devrait il pas initialiser un tableau a trois dimension ?
    En théorie, on devrait faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Pnj pnj[5] = 
    { 
       {{0},0,0,0,0},
       {{0},0,0,0,0},
       {{0},0,0,0,0},
       {{0},0,0,0,0},
       {{0},0,0,0,0},
    };
    J'ai utilisé une forme simplifiée, car les autres éléments sont automatiquement mis à 0.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 75
    Par défaut
    Cette question est grave. Tu ne lis donc pas la doc des fonctions que tu utilises ?
    Non Je sais que je devrais m'y mettre, mais l'anglais est assez rebutant.

    J'ai utilisé une forme simplifiée, car les autres éléments sont automatiquement mis à 0.
    Ok.

    Même si mon premier problème est résolus, je vien d'en rencontré un autre.

    J'essayais de faire un test pour vérifier que lorsqu'on déplace un personnage il n'y ait pas de pnj sur la case ou le personnage va mais cela ne marche pas, et mon compilo m'affiche des avertissements.

    deplacement.c:33: warning: comparison between pointer and integer
    deplacement.c:51: warning: comparison between pointer and integer
    deplacement.c:69: warning: comparison between pointer and integer
    deplacement.c:87: warning: comparison between pointer and integer
    :: === Génération finie: 0 erreurs, 4 avertissements ===
    Voici le code :

    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
    int deplacement(int carte[][NB_BLOCS_LARGEUR],int keydown_type, InfoPosition *infos,Pnj *pnj[])
    {
         int bouge = 1;
         int d=RIEN;
         int i=0, test_pnj=0;/*Booléen pour tester si il y a un pnj*/
     
         if(infos->actif != 0)
         {
            switch(keydown_type)
            {
              case HAUT:
                   if(carte[infos->jy-1][infos->jx]!=MER &&
                      carte[infos->jy-1][infos->jx]!=MONTAGNE &&
                      carte[infos->jy-1][infos->jx]!=LAC)
                   {
                       for(i=0;i<NB_PNJ;i++)
                       {
                           if(infos->jy-1==pnj[i]->y && infos->jx==pnj[i]->x) /*Bug ici*/
                           {
                             test_pnj=1;
                           }
                       }
                       if(pnj!=1)
                       {
                         infos->jy--;
                       }
                   }
                   d=HAUT;
                   break;
     
              case BAS:
                   if(carte[infos->jy+1][infos->jx]!=MER && 
                      carte[infos->jy+1][infos->jx]!=MONTAGNE && 
                      carte[infos->jy+1][infos->jx]!=LAC)
                   {
                       for(i=0;i<NB_PNJ;i++)
                       {
                           if(infos->jy+1==pnj[i]->y && infos->jx==pnj[i]->x)/*Ici*/
                           {
                             test_pnj=1;
                           }
                       }
                       if(pnj!=1)
                       {
                          infos->jy++;
                       }
                   }
                   d=BAS;
                   break;
     
              case GAUCHE:
                   if(carte[infos->jy][infos->jx-1]!=MER && 
                      carte[infos->jy][infos->jx-1]!=MONTAGNE && 
                      carte[infos->jy][infos->jx-1]!=LAC)
                   {
                       for(i=0;i<NB_PNJ;i++)
                       {
                           if(infos->jx-1==pnj[i]->x && infos->jy==pnj[i]->y)/*Ici*/
                           {
                             test_pnj=1;
                           }
                       }
                       if(pnj!=1)
                       {
                         infos->jx--;
                       }
                   }
                   d=GAUCHE;
                   break;
     
              case DROITE:
                   if(carte[infos->jy][infos->jx+1]!=MER && 
                      carte[infos->jy][infos->jx+1]!=MONTAGNE && 
                      carte[infos->jy][infos->jx+1]!=LAC)
                   {
                       for(i=0;i<NB_PNJ;i++)
                       {
                           if(infos->jx+1==pnj[i]->x && infos->jy==pnj[i]->y)/*Et la*/
                           {
                             test_pnj=1;
                           }
                       }
                       if(pnj!=1)
                       {
                         infos->jx++;
                       }
                   }
                   d=DROITE;
                   break;
              default:
                   bouge = 0;
                   break;
            }
         }
     
         if(bouge == 1)
         {
             gestionScrolling(infos);
         }return d;
    }
    Merci d'avance.

  7. #7
    Membre confirmé Avatar de Beldom
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 63
    Par défaut
    Non Je sais que je devrais m'y mettre, mais l'anglais est assez rebutant.
    Les man de Devellopez sont en français... Maintenant que tu le sais, tu peux les lire

    Pour ton problème, il faudrait les deux structures. Je présume que pnj, on l'a, mais je n'ai pas vu InfoPosition

    Enfin, là le problème viens clairement du fait que l'une de tes deux valeurs est un int, je dirais infos->jy-1, puisque tu n'as pas de warning pour carte[infos->jy-1][infos->jx].
    (En effet, pour qu'il n'y ai pas de Warning à la compilation, cela signifie que infos->jy et infos->jx sont reconnus comme des int)


    Et que l'autre est un pointeur. Donc il doit s'agir de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pnj[i]->x
    // et
    pnj[i]->y
    Et comme ca, je dirais que ca viens de la manière dont tu déclares pnj... Pnj *pnj[]... Tu es sûr que tu ne voulais pas plutôt écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int deplacement(int carte[][NB_BLOCS_LARGEUR],int keydown_type, InfoPosition *infos, Pnj *pnj)
    ??

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 7
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ...
               for(i=0;i<NB_PNJ;i++)
               {
                   if(infos->jy-1==pnj[i]->y && infos->jx==pnj[i]->x) /*Bug ici*/
                   {
                     test_pnj=1;
                   }
               }
               if (pnj!=1) // Tu veux surement dire test_pnj != 1
               {
                 infos->jy--;
               }
    ...
    Ah et y avait une petite coquille dans mon premier post, je sais pas si tu t'en est rendu compte mais on devrait lire pnj[i]->nom et non &pnj[i]->nom.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 20/10/2006, 13h19
  2. Accès le plus rapide: Pointeur ou tableau?
    Par homeostasie dans le forum C
    Réponses: 21
    Dernier message: 01/09/2006, 14h08
  3. [VB.NET] Pointeur vers tableau
    Par b_lob dans le forum Windows Forms
    Réponses: 4
    Dernier message: 31/08/2006, 16h06
  4. convertion pointeur vers tableau
    Par gdpasmini dans le forum C++
    Réponses: 2
    Dernier message: 30/03/2006, 00h34
  5. Pointeur et TAbleau
    Par melmouj dans le forum C
    Réponses: 20
    Dernier message: 25/09/2005, 16h13

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