[C]tableau de structure a 2 dimension et fonc

Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   -  
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour / Bonsoir,

actuellement sur un projet en C, je me retrouve a devoir manipuler un tableau de structure à deux dimension dans une fonction. Après plusieurs essai infructueux le programme ce lance enfin pour laisser place a un magnifique message Windows me prévenant que le programme c'était fermer inopinément. Je vous communique mon code afin que vous puissiez éventuellement m'aider.

int main ( int argc, char** argv ) 
{ 

    coord tab_fond[NB_HAUT-1][NB_LARG-1]; 

    /* je n'ais laisser que le parti du code utile, le programme s'arrête a l'appel de la fonction.*/ 

    remplissage(tab_fond);

et voici ma structure :

typedef struct coord coord; 
struct coord{ 
    int x; 
    int y; 
};


et enfin ma fonction remplissage :

void remplissage (coord tab[NB_HAUT-1][NB_LARG-1]){ 
    int h=0, k=0; 

    for (h=0;h<NB_LARG; h++){ 
        for(k=0; k<NB_HAUT; k++){ 
            tab[h][k].x=10; 
            tab[h][k].y=10; 
        } 
    } 
} 

Merci d'avance de vos réponse.
A voir également:

14 réponses

nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
Très simple : tu as interverti largeur et hauteur dans l'accès au tableau !
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Merci cela a régler le problème, ou tout du moins cela a arrêter de faire planter la programme. Cependant si je peut abuser de votre générosité, ces lignes sembles posée problème :

for (i=0;i<NB_HAUT; i++){
        for(j=0; j<NB_LARG; j++){
            fond = IMG_Load("images/fond.png");
            fond_herbe.x=(tab_fond[i][j].x)*TAI_BLOC;
            fond_herbe.y=(tab_fond[i][j].y)*TAI_BLOC;
            SDL_BlitSurface(fond,&fond_herbe,ecran,&pos_fond);
            pos_fond.x+=TAI_BLOC;
        }
        pos_fond.y+=TAI_BLOC;
        pos_fond.x=0;

    }


a moins que le problème ne vien de ma fonction :

void remplissage (coord tab[NB_HAUT-1][NB_LARG-1]){
    int h=0, l=0;

    for (h=0;h<NB_HAUT; h++){
        for(l=0; l<NB_LARG; l++){
            tab[h][l].x=10;
            tab[h][l].y=10;
        }
    }

    tab[27][18].x=3;
    tab[27][18].y=5;
}


Merci d'avance.
0
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
Je te précise tout de même que je maitrise presque rien du C, mais en tous cas je ne vois rien de flagrant là, quel problème se fait sentir ?
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
En flagrant,moi j'aimerais bien savoir d'où sortent les 27 et 18 à la fin...
Est-ce que l'inversion a également été respecté pour ces deux valeurs ?
0
zeroc00l0 Messages postés 1 Date d'inscription   Statut Membre Dernière intervention  
 
tab[h][l].x=4; 
tab[h][l].y=4; 

pour remplir la carte d'herbe.

tab[20][18].x=10;
tab[20][18].y=10; 

pour mettre une fleur aux coordonnées (20 ; 18)


Le problème est que arrivé à i = 24 dans la boucle suivante, la carte ne se dessine plus :
Sachant que NB_LARG = 30 et NB_HAUT = 25

for (i=0;i<NB_LARG; i++){ 
        for(j=0; j<NB_HAUT; j++){ 
            fond_herbe.x=(tab_fond[i][j].x)*TAI_BLOC; // récupération des coordonnés dans l'image pour la découpe
            fond_herbe.y=(tab_fond[i][j].y)*TAI_BLOC; 
            SDL_BlitSurface(fond,&fond_herbe,ecran,&pos_fond); 
            pos_fond.y+=TAI_BLOC; //je pase au groupe de 16 px suivant
        } 
        pos_fond.x+=TAI_BLOC; 
        pos_fond.y=0; // je remet a 0 le compteur de ligne

    } 


Il y a donc un bandeau noir de 5*16 px par 24*16px sur la droite de la carte.
Je pense qu'il postera un screenshot d'ici peu.
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Le programme ce lance puis après quelques secondes de chargement, ce ferme et une fenêtre windows s'ouvre pour signifier que le programme a cesser de fonctionner ...
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
L'erreur la plus fréquente serait que tu essayes d'accéder à une case de tableau qui n'existe pas.
Par exemple si tab[27][18] n'est pas correct !
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
en effet, je m'embrouille totalement entre les X et les Y, les dimensions max sont tab[24][29], merci de pointer une si bête erreur. Cela dit, a présent que le programme ce lance, la fenêtre reste noir au lieu de 749 bloque d'herbe et d'une fleure. Une idée ?

Cela est sans doute dus a une erreur dans ma boucle for.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Commence par contrôler les codes de retour de tes fonctions.
Par exemple SDL_BlitSurface est censé renvoyé 0 en cas de succès. Sinon il peut renvoyer -1 ou -2. Il en va de même pour toutes les autres fonctions.
Donc affiche une trace des codes d'erreurs s'il y en a pour les identifier.

Par exemple :

int err = SDL_BlitSurface(fond,&fond_herbe,ecran,&pos_fond);

if (err!=0)
{
   printf("SDL_BlitSurface : err=%d i=%d j=%d\n",err,i,j);
   exit(1);
}
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Merci du conseil, il faudra que j'y pense plus souvent. Mais il n'y a aucun problème au niveau du blitage, je su pose donc que le problème viens de mon tableau qui est renvoyé null ou vide. mes coordonnées envoyés ne correspond donc a rien dans mon image.
0
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
Peut-être que le tableau est passé en constante à la fonction, ce qui fait que la fonction travaille sur une copie de ce tableau sans modifier celui passé en paramètre...
De plus, la fonction de remplissage se contente de mettre 10 en coordonnées X et Y...
Je pense que l'idéal serait que tu utilises le débugger, il te permettrais de voir l'évolution pas-à-pas des coordonnées d'affichage de l'image et donc d'en vérifier la pertinence. Et puis ce serait l'occasion d'apprendre à t'en servir, et il vaut mieux s'y mettre le plus tôt possible car c'est l'outil incontournable du programmeur...
Quant aux confusions X et Y, il suffit d'adopter certaines conventions telles que placer toujours X en premier dans la définition du tableau et utiliser des variables d'indices dont les labels contiennent X et Y...
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Le débogueur (déjà utiliser auparavant) m'a permis de remarquée que certaines variable bien qu'initialiser a 0 ce retrouvai suite a l'appel de ma fonction à des valeurs aléatoire (4 et 10 étant des valeurs récurrentes).
Cependant, le tableau lui est initialiser correctement a la sortie de ma fonction mais ma fenêtre elle ne se rempli pas correctement, en effet, une fois un carrée de 24 par 24 case remplit, les 5 derniers colonne ne sont pas remplis comme elle le devrait, et cela reste pour moi un mystère.

Merci encore pour vos réponse rapide est pertinentes.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Le problème de passage du tableau soulevé par nicocorico est pertinent. Bien qu'il ne soit pas tout à fait question de passage par copie en C, la question se pose quand même quant à savoir si le tableau en sortie a bien été modifié.

En plus, je viens de lever un lièvre, à moins que tu ne l'ai modifié depuis, ton tableau a des dimensions NB_HAUT-1 et NB_LARG-1, en conséquence les indices autorisés sont de 0 à NB_HAUT-2 et de 0 à NB_LARGE-2. Donc dans tes boucles for la condition d'arrêt est fausse puisque tu t'autorises à aller jusqu'à NB_HAUT-1 et NB_LARGE-1 !

for (h=0;h<NB_HAUT-1; h++)
for (l=0; l<NB_LARG-1; l++)
{
    tab[h][l].x=10;
    tab[h][l].y=10;
}
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Bonjours, ce problème a été résolus, en effet. pour simplifier les choses je vais vous envoyez mon code complète, il n'est pour l'instant pas très long:

#include <stdio.h> 
#include <stdlib.h> 
#include <SDL/SDL.h> 
#include <SDL_image.h> 
#include "constantes.h" 
#include "main.h" 


int main ( int argc, char** argv ) 
{ 
    SDL_Surface *ecran=NULL, *fond; 
    SDL_Rect fond_herbe, pos_fond; 
    int i=0, j=0; 
    int err=0; 
    coord tab_fond[NB_HAUT-1][NB_LARG-1]; // mon tableau de structure

    remplissage(tab_fond); // ma fonction qui permet d'initialiser les coordonées

    fond_herbe.w=TAI_BLOC; //la hautre en pixel (16) a récupérer de mon tilset (l'image fond.png)
    fond_herbe.h=TAI_BLOC; 

    if (SDL_Init(SDL_INIT_VIDEO)==-1){ 
        fprintf(stderr, "Erreur initialisation SDL: %s\n", SDL_GetError()); 
        exit(EXIT_FAILURE); 
   } 


    ecran =SDL_SetVideoMode(LAR_FEN, HAU_FEN, 32, SDL_HWSURFACE); 
    fond = IMG_Load("images/fond.png"); // chargement de mon image a couper puis bliter.
    pos_fond.x=0; //initialisation des point de départ du blitage
    pos_fond.y=0; 

    for (i=0;i<NB_LARG; i++){ 
        for(j=0; j<NB_HAUT; j++){ 
            fond_herbe.x=(tab_fond[i][j].x)*TAI_BLOC; // récupération des coordonnés dans l'image pour la découpe
            fond_herbe.y=(tab_fond[i][j].y)*TAI_BLOC; 
            SDL_BlitSurface(fond,&fond_herbe,ecran,&pos_fond); 
            pos_fond.y+=TAI_BLOC; //je pase au groupe de 16 px suivant
        } 
        pos_fond.x+=TAI_BLOC; 
        pos_fond.y=0; // je remet a 0 le compteur de ligne

    } 

    SDL_Flip(ecran); 
    pause(); 
    SDL_FreeSurface(fond); 

    SDL_Quit(); 
    return EXIT_SUCCESS; 
} 

void pause(){ 
    int continuer=1; 
    SDL_Event event; 

    while(continuer){ 

        SDL_WaitEvent(&event); 
        switch(event.type){ 
            case SDL_QUIT: 
                continuer=0; 
        } 
    } 
} 

void remplissage (coord tab[NB_HAUT-1][NB_LARG-1]){ 
    int h=0, l=0; // mes deux compteurs

    for (h=0;h<NB_HAUT; h++){ //début de la boucle pour le remplissage de mon tableau
        for(l=0; l<NB_LARG; l++){ 
            tab[h][l].x=4; 
            tab[h][l].y=4; 
        } 
    } 

    tab[20][18].x=10; //initialisation d'une autre cas (pour vérifier que tout marche bien)
    tab[20][18].y=10; 
} 


Merci de prendre du temps pour le pauvre programmeur en herbe (et perdus) que je suis.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
L'erreur dont je parlais est toujours présente : tu ne peux par faire for (h=0;h<NB_HAUT; h++) alors que tab[h] est un tableau de taille NB_HAUT-1 ! Idem pour l et NB_LARG !!
Et vu ton code tu as cette erreur partout !

En plus il n'y a aucune raison d'avoir 20 et 18 qui se promènent. Tu as des constantes sers-t-en !

Et pour éviter les erreurs de passage du tableau, il pourrait être préférable de le passer en variable globale !

#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL_image.h>
#include "constantes.h"
#include "main.h"

#define FLEUR_X 18
#define FLEUR_Y 20

#define PAVE_HERBE 4
#define PAVE_FLEUR 10

#define MAXY NB_HAUT-1
#define MAXX NB_LARG-1

coord tab[MAXY][NB_LARG-1];

void remplissage()
{
    int x,y

    for (y=0; y<MAXY; y++)
    for (x=0; x<MAXX; x++)
    {
        tab[y][x].x=PAVE_HERBE;
        tab[y][x].y=PAVE_HERBE;
    }

    tab[FLEUR_Y][FLEUR_X].x=PAVE_FLEUR;
    tab[FLEUR_Y][FLEUR_X].y=PAVE_FLEUR;
}

void pause()
{
    SDL_Event event;

    while(1)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                return;
        }
    }
}

int main()
{
    remplissage();

    if (SDL_Init(SDL_INIT_VIDEO)==-1)
    {
        fprintf(stderr, "Erreur initialisation SDL: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }

    SDL_Surface *ecran = SDL_SetVideoMode(LAR_FEN, HAU_FEN, 32, SDL_HWSURFACE);
    SDL_Surface *fond = IMG_Load("images/fond.png");
    pos_fond.x=0;
    pos_fond.y=0;

    SDL_Rect pos_fond, fond_herbe;
    fond_herbe.w=TAI_BLOC;
    fond_herbe.h=TAI_BLOC;

    int x,y;
    for (y=0; y<MAXY; y++)
    {
        for(x=0; x<MAXX; x++)
        {
            fond_herbe.x=(tab[y][x].x)*TAI_BLOC;
            fond_herbe.y=(tab[y][x].y)*TAI_BLOC;

            SDL_BlitSurface(fond,&fond_herbe,ecran,&pos_fond);
            pos_fond.y+=TAI_BLOC;
        }

        pos_fond.x+=TAI_BLOC;
        pos_fond.y=0;
    }

    SDL_Flip(ecran);
    pause();
    SDL_FreeSurface(fond);
    SDL_Quit();
    return EXIT_SUCCESS;
}
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Les prédictions de zeroc00l0 ce réalisent, voici le résultat:

http://www.noelshack.com/
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Up svp, le problème persiste a me bloquer, personne n'as d'idée ?
0
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
As-tu bien pris en considération les modifications apportées par Kx dans son dernier post ? sinon, mieux vaut commencer par là....
0
Panda jack Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   7
 
Oui oui, je l'ai en effet pris en conte (et donc modifier mon code en conséquence) et le problème reste le même.
0