PDA

Voir la version complète : Matrice à partir d'un fichier texte


Bap65
10/05/2008, 12h59
Bonjour à tous, je vais avoir besoin d'un petit coup de pouce pour le développement d'une petite fonction (pas difficile en soit) mais qui me donne tout de même du fil à retordre :hmm:

C'est très simple: J'ai un fichier texte qui se présente de la sorte:

1 0 0 0 1 0 0 1 1
0 1 0 1 0 0 1 0 0
0 1 1 1 0 0 0 0 0
0 1 0 1 0 0 1 0 0
1 1 1 1 1 0 0 0 1

Etc...

Je veux récuperer les valeurs (donc les 0 ou les 1) en int dans ma matrice.

Voici ma fonction: (Programme en C)

void init_tab(int **a){
FILE *matrice;
int x,y;

matrice=fopen("matrice/matrice1.txt","r");

for (y=0;y<=49;y++){
for (x=0;x<=49;x++){
fscanf(matrice,"%f ",a[x][y]);
}
}

int fclose(FILE* matrice1);

}

a, c'est la matrice en question
x et y servent à l'incrémentation (c'est un tableau de 50x50)
J'utilise les librairie sdl, stdio et stdlib

Bon, j'ai essayé tout pleins de formules à côté, avec getc avec tout plein d'autres trucs mais je n'arrive pas à avoir quelquechose qui fonctionne :cry:
Je ne me préoccupe pas des retour Chario pour le moment, je m'en préocuperai quand j'aurais déja réussi à remplir ma première ligne du tableau. ;)

N'auriez-vous pas la bonne solution pour lire le fichier texte et remplir le tableau efficacement ?

Merci pour votre aide ! :wub:

Cortes48
10/05/2008, 13h37
Je pense que l' erreur vient de :

fscanf(matrice,"%f ",a[x][y]);

C' est le "%f".

Dans ta boucle for, le %f reste le premier caractere de ton fichier je crois.
Il faut essayer de trouver une méthode pour l' incrémenter

dolarcles
10/05/2008, 13h43
Bon déjà avant toutes choses, ajoute un
if (matrice!=NULL) pour être sûr que ton fichier est correctement ouvert. Ensuite, fscanf je l'aime pas. Une manière propre aurait été d'avoir simplement un fichier binaire (pas du ascii de merde et sans espace) et tu l'aurais simplement copié en mémoire à l'emplacement d'un pointeur.

Bap65
10/05/2008, 13h48
Bon, j'ai un peu rebidouillé entre deux, et maintenant ça fonctionne OO'

Pour le coup du %f, d'une part je m'étais gouré dans l'exemple au dessus et je n'ai pas rectifié après avoir testé, c'est bien un "%d" pour un entier.

Bon, ça à l'air de fonctionner avec ceci:

for (y=0;y<=49;y++){
for (x=0;x<=49;x++){
//a[x][y] = fgetc(matrice);
fscanf(matrice,"%d ",&a[x][y]);
}
}

Il y a également le "&" qui va servir à localiser l'adresse de destination.
De plus, il faut bien mettre "%d " avec l'espace pour sauter les valeurs. Le fscanf s'autoincrémente ;)

Bon jusque là j'arrive à afficher ma première ligne :bave: Je vous resoliciterais si besoin, en attendant, merci Cortes (et Dolarcles, message ajouté après que je clique sur poster) ^^

Bap65
12/05/2008, 14h10
Bon, me revoilà avec un autre problème (idiot, naturellement, sinon se serait pas fun) !

Alors... J'ai donc dans mon programme déclaré ma matrice ainsi:

int **a;
a=(int**) malloc (50*sizeof(int));
for(x=0;x<50;x++) a[x] = (int * )malloc(50*sizeof(int));

Ainsi j'ai ma matrice avec mémoire allouée dynamiquement.

Après, je balance ma matrice dans une fonction, comme ceci:

calcMatr(a);

Et enfin, voici ma fonction:

void calcMatr(int **a, int **b){
int x,y,i,j,nb=0;

for (x=1;x<=48;x++){
for (y=1;y<=48;y++){

for (i=(x-1);i<=(x+1);i++){
for (j=(y-1);j<=(y+1);j++){
if (a[i][j]==1){nb++;}
}
}
if (nb> 3) {a[i][j]=1;}
nb=0;
}
}
}

Le but, c'est de balayer ma matrice et d'effectuer des opérations dessus.

Le gros soucis, c'est que lorsque cette fonction est effectuée, le programme s'arrète imédiatement...
Après débug, ce qui fait planter le truc, c'est clairement:

if (nb> 3) {a[i][j]=1;}


J'aimerais savoir si vous voyez ou est le soucis, si je n'ai pas utilisé la bonne synthaxe, si je ne me suis pas embrouillé dans mes pointeurs... etc...

Merci pour votre aide ! :wub:

Portnaouak
12/05/2008, 14h19
Pourquoi utiliser 4 variables pour parcourir ta matrice ? 2 suffisent amplement non ?

yaouank
12/05/2008, 14h29
déjà un point qui ne changera rien je pense mais qu'il faut corriger:

a=(int**) malloc (50*sizeof(int*));

Ensuite: supprimer la variable b que tu as mise dans l'entete de ta fonction.
Enfin: t'as pensé à initialiser quelque part la valeur de toutes les cases du tableau a ? Du genre

for (int x=0; x<50; x++)
{
for (int y=0; y<50; y++)
{
a[x][y]=0;
}
}


Dernière question: t'es sûr de ce que t'es en train de faire ? Parce que ça semble un peu bizarre d'écrire dans le tableau a alors que t'es en train de le lire. C'est possible que ce soit exactement ce que tu veuilles faire, c'est juste pour être sûr.

Et c'est peut-être trop tard mais je te conseille de passer plutôt par des a[50 * y + x] plutot que des a[x][y]. Ca fait moins de malloc à faire et après t'as pas à te demander s'il fallait pas mettre des parenthèses ici et là quand ton code commence à planter inexplicablement (du genre (a[x])[y] ).

Et dans la série des conseils:
remplacer tes 50 par des
#define LARGEUR_TABLEAU (50)
ou
const int largeurTableau=50;
Et donc, du coup, tes "for (y=0;y<=49;y++)" par des "for (y=0; y< LARGEUR_TABLEAU; y++)"


Et pour te répondre: je ne vois aucun gros bug me sauter aux yeux quand je lis ton code.

Bap65
12/05/2008, 14h30
Pourquoi utiliser 4 variables pour parcourir ta matrice ? 2 suffisent amplement non ?

Je dois parcourir de 2 manières différentes à chaque fois (pour compter le nombre de points actifs autour d'une certaine case.

Problème résolut ! Vous m'avez permis de pointer une grosse erreur de ma part, il suffisait de remplacer:

if (nb> 3) {a[i][j]=1;}
par
if (nb> 3) {a[x][y]=1;}

Vous voyez, comme quoi je sentais que c'était tout con :D

Encore merci les zamis !! :wub:


déjà un point qui ne changera rien je pense mais qu'il faut corriger:

Code:
a=(int**) malloc (50*sizeof(int*));

Est-ce vraiment nécessaire ? Après tout, ce que je veux c'est simplement lui demander de réserver l'espace nécessaire à un entier, pas d'un pointeur d'entier.
Ou c'est la même chose ?

Foxy
12/05/2008, 14h51
Et c'est peut-être trop tard mais je te conseille de passer plutôt par des a[50 * y + x] plutot que des a[x][y]. Ca fait moins de malloc à faire et après t'as pas à te demander s'il fallait pas mettre des parenthèses ici et là quand ton code commence à planter inexplicablement (du genre (a[x])[y] ).

C'est plutot a[50 * x + y], en effet si on accede au tableau par a[x][y], les colonnes sont en x et les lignes en y :)

Par contre un truc qui me chifonne, c'est pourquoi un pointeur sur pointeur ? (int **a) ??

Bap65
12/05/2008, 15h34
Alors tout d'abord pour Yaouank:

Pour le b, j'ai juste oublié de l'enlever dans l'exemple ci-dessus, en réalité, je l'envois de la même manière que le a, je récupère 2 matrices.

Ensuite oui, mon tableau est bien initialisé, par une autre fonction (voir premier post)

Pour ce que je suis en train de faire, actuellement ça n'a pas encore de sens, c'était juste comme je l'ai dit un test pour voir si je pouvais ecrire efficacement dans une matrice, et comme j'utilise la SDL, je n'ai pas de Printf, donc le seul moyen de débugger, c'est de faire ce genre de petites actions incohérentes ;)
Dans ce cas, ça me permet d'étendre une population de point et donc vérifier en même temps que toutes mes cases sont bien gérée ;)

Donc là pas de soucis, a présent je vais pouvoir bosser sur la mise en place de mon système de double matrice :) (a et b)

Pour Foxy:
Pour avoir un pointeur qui pointe sur un tableau d'autres pointeurs de tableaux :p

yaouank
12/05/2008, 16h25
Est-ce vraiment nécessaire ? Après tout, ce que je veux c'est simplement lui demander de réserver l'espace nécessaire à un entier, pas d'un pointeur d'entier.
Ou c'est la même chose ?
Tu veux reserver l'espace necessaire à 50 pointeurs d'entiers. Pas à 50 entiers.
La ça doit marcher parce qu'un "int*" fait la meme taille en mémoire qu'un "int"

Mais si tu avais travaillé avec des "char", ca n'aurait pas fonctionné:
Le code suivant aurait explosé dès que tu aurais tenté d'écrire toto[12]

char ** toto = (char**)malloc(50*sizeof(char));


C'est plutot a[50 * x + y], en effet si on accede au tableau par a[x][y], les colonnes sont en x et les lignes en y :)
Quel pinailleur :p

De toute façon, ça marche dans tous les sens (ça dépend de comment on définit x et y et de comment on parcourt le tableau à 1 dimension).
Mais je reste sur l'idée que quand la majorité des développeurs écrit a[coord1][coord2], coord1 correspond à l'abscisse et coord2 à l'ordonnée.
Et ça, pour la majorité des développeurs, dans une image stockée dans un tableau à 1 dimension, on y accède par image[coord2*LARGEUR+coord1]

Bref je suis d'avis que le classique a[x][y] doit être associé à un a[LARGEUR*y+x] et non a[HAUTEUR*x+y]
(sauf sur gamepark32 ou une autre machine diabolique qui a décidé de ne pas faire comme tout le monde et de stocker les images colonnes par colonnes).

C'était la dérive de YaouanK...

Bap65
12/05/2008, 17h10
Tu veux reserver l'espace necessaire à 50 pointeurs d'entiers. Pas à 50 entiers.
La ça doit marcher parce qu'un "int*" fait la meme taille en mémoire qu'un "int"


Ah oui, effectivement, c'est bien vu ça :)

De toute façon, ça marche dans tous les sens (ça dépend de comment on définit x et y et de comment on parcourt le tableau à 1 dimension).
Mais je reste sur l'idée que quand la majorité des développeurs écrit a[coord1][coord2], coord1 correspond à l'abscisse et coord2 à l'ordonnée.


Pour ce qui est de l'ordre [x] et [y] c'est pas très important lorsque je lis mes valeurs. Par contre là ou ça importe, c'est lorsque j'ecris, car je peux me retrouver avec une matrice tournée de 90° :p

M'enfin à cet instant précis, mon projet est fini :fleur:
Je vous le posterais ici un ptit peu plus tard si ça vous interesse, juste 2 - 3 ptits trucs à corriger. :bave:

C'était la dérive de YaouanK...

Non au contraire, c'est super interessant, et c'est comme ça que l'on apprend des tas de trucs ^^

Merci beaucoup en tout cas ! :wub:

archipel
12/05/2008, 18h56
M'enfin à cet instant précis, mon projet est fini :fleur:
Je vous le posterais ici un ptit peu plus tard si ça vous interesse, juste 2 - 3 ptits trucs à corriger. :bave:
un picross?