Accéder aux données d'un fichier [C++] - Programmation
Marsh Posté le 25-03-2001 à 19:54:34
Eh bien il me semble que tu as oublié d'appeler la fonction "read_material()" dans ton main()... Elle n'est donc pas exécutée !
Marsh Posté le 25-03-2001 à 20:03:26
Mais que je suis con... J'ai rajouté read_mesh () dans main().
Maintenant ça plante tout court.
Une idée du problème?
Marsh Posté le 25-03-2001 à 20:39:33
Il y a effectivement des trucs qui attirent mon attention... :
* Pour le "fread (&listvertices, sizeof (float), nvertices, bin3ds)", il y a un risque de mauvaise compatibilité entre ce que tu lis dans le fichier (un float) et le type que tu as déclaré pour listvertices (un double).
* Pour le "printf ("%s", listvertices)" , il y a une erreur d'affichage car il faut utiliser "%ld" pour afficher un double ("%s" est réservé aux chaines de caractères).
* La condition de sortie de la boucle n'interrompt pas la fonction assez tôt : lorsque tu écris
if (feof (bin3ds))
{
done = 1;
}
tu détectes bien la fin du fichier, mais les instructions suivantes sont quand même effectuées, et tu fais donc toutes les opérations avec des données non valides. Il faut utiliser soit un "break" pour provoquer la sortie de la boucle, soit mettre les instructions suivantes dans un bloc "else {...}" .
Voilà, je pense que ça règlera quelques-uns de tes problèmes !...
Marsh Posté le 25-03-2001 à 21:45:36
J'ai fais les changements, mais ça plante toujours.
Si je lance le débuggeur de Visual C++, le programme me signale la première erreure au premier feof (bin3ds).
Marsh Posté le 25-03-2001 à 22:07:12
Il est possible que cette erreur soit due à l'échec de fopen :
effectue le test suivant pour vérifier que le fichier est réellement ouvert :
if ( bin3ds == NULL )
{
// Erreur : Le fichier n'a pas été ouvert
}
Si le problème vient de là, il faut que tu inscrives le chemin complet d'accès au fichier que tu veux ouvrir en n'oubliant pas de respecter la syntaxe particulière des chaines de caractères :
"C:\\mon_rep\\mon_fichier.3ds"
En fait, il est important de faire ce test à chaque fois que tu veux accèder à un fichier, car en cas d'échec de l'ouverture toutes les autres fonctions ( fread,fclose,... ) provoquent des résultats imprévisibles ou des pannes complètes.
Marsh Posté le 25-03-2001 à 22:16:02
Je viens de tester, et le problème ne vient pas de là.
A mon avis j'ai fait une erreur dans la recherche des chunks 3DS du fichier. Mais alors je n'ai aucune idée de comment la résoudre.
Marsh Posté le 27-03-2001 à 07:09:15
Aucune idée? Je sais vraiment pas quoi faire. Au alors dites moi qui contacter pour m'aider.
SVP
Marsh Posté le 27-03-2001 à 07:39:40
Tu executes ton prog pas a pas ?
Si oui, peux-tu confirmer que bin3ds est non-nulle au premier appel de feof() et que c'est la que ca plante ?
Marsh Posté le 27-03-2001 à 18:21:03
Voilà ce que ça donne quand je lance le programme:
J'ai ajouté un test pour voir si bin3ds == NULL avant le premier feof mais le texte d'erreur ne se mets pas en route, donc ça doit pas venir de là.
Marsh Posté le 27-03-2001 à 18:22:51
ca doit etre une erreur de pointeur ou d'ouverture de fichier
Marsh Posté le 27-03-2001 à 18:25:48
Je pense aussi, je dirais que le programme ne cherche pas correctement les chunks dans le fichier 3DS, mais je sais pas comment vérifier ça.
Marsh Posté le 28-03-2001 à 00:45:12
mais pourquoi tu n'executes pas ton prog pas a pas pour localiser exactement le probleme ??
Marsh Posté le 25-03-2001 à 19:20:31
Bon, voilà le code que j'ai écrit pour charger un objet se trouvant dans un fichier 3DS.
#include <windows.h>
#include <stdio.h>
///////////////////////////////////////////////////////////////////
//Mesh
char objectname [256];
WORD nvertices;
WORD nfaces;
double listvertices;
double listfaces;
double listuvcoord;
//Material
char materialname [256];
double ambient;
double diffuse;
double specular;
//Mapping
char texturename [256];
float uscale; float vscale;
double listuvscale [2] = {uscale, vscale};
float uoffset; float voffset;
double listuvoffset [2] = {uoffset, voffset};
float rotationangle;
///////////////////////////////////////////////////////////////////
FILE *bin3ds;
///////////////////////////////////////////////////////////////////
unsigned char ReadChar ()
{
return (fgetc (bin3ds));
}
unsigned int ReadInt ()
{
unsigned int temp = ReadChar ();
return (temp | (ReadChar () << 8));
}
///////////////////////////////////////////////////////////////////
int read_material (void)
{
bin3ds = fopen ("box.3ds", "r" );
WORD id;
int done = 0;
while (done != 1)
{
if (feof (bin3ds))
{
done = 1;
}
id = ReadInt ();
switch (id)
{
case 0xA000: //Material Name
{
int i = 0;
char ch;
while ((ch = fgetc (bin3ds)) != 0)
{
materialname [i] = ch;
i++;
}
materialname [i] = '\0';
}
break;
case 0xA010: //Ambient Color
{
short red;
short green;
short blue;
double redambient;
double greenambient;
double blueambient;
fread (&red, sizeof (byte), 1, bin3ds);
fread (&green, sizeof (byte), 1, bin3ds);
fread (&blue, sizeof (byte), 1, bin3ds);
redambient = (1/255)*red;
greenambient = (1/255)*green;
blueambient = (1/255)*blue;
ambient = (redambient, greenambient, blueambient);
}
break;
case 0xA020: //Diffuse Color
{
short red;
short green;
short blue;
double reddiffuse;
double greendiffuse;
double bluediffuse;
fread (&red, sizeof (byte), 1, bin3ds);
fread (&green, sizeof (byte), 1, bin3ds);
fread (&blue, sizeof (byte), 1, bin3ds);
diffuse = (reddiffuse, greendiffuse, bluediffuse);
}
break;
case 0xA030: //Specular Color
{
short red;
short green;
short blue;
double redspecular;
double greenspecular;
double bluespecular;
fread (&red, sizeof (byte), 1, bin3ds);
fread (&green, sizeof (byte), 1, bin3ds);
fread (&blue, sizeof (byte), 1, bin3ds);
specular = (redspecular, greenspecular, bluespecular);
}
break;
}
}
fclose (bin3ds);
return 0;
}
int read_mapping (void)
{
bin3ds = fopen ("box.3ds", "r" );
WORD id;
int done = 0;
while (done != 1)
{
if (feof (bin3ds))
{
done = 1;
}
id = ReadInt ();
switch (id)
{
case 0xA300: //Mapping Filename
{
int i = 0;
char ch;
while ((ch = fgetc (bin3ds)) != 0)
{
texturename [i] = ch;
i++;
}
texturename [i] = '\0';
}
break;
case 0xA354: //V Scale
{
fread (&vscale, sizeof (float), 1, bin3ds);
}
case 0xA356: //U Scale
{
fread (&uscale, sizeof (float), 1, bin3ds);
}
case 0xA358: //U Offset
{
fread (&uoffset, sizeof (float), 1, bin3ds);
}
case 0xA35A: //V Offset
{
fread (&voffset, sizeof (float), 1, bin3ds);
}
case 0xA35C: //Rotation Angle
{
fread (&rotationangle, sizeof (float), 1, bin3ds);
}
}
}
fclose (bin3ds);
return 0;
}
int read_mesh (void)
{
bin3ds = fopen ("box.3ds", "r" );
WORD id;
int done = 0;
while (done != 1)
{
if (feof (bin3ds))
{
done = 1;
}
id = ReadInt ();
switch (id)
{
case 0x4000: //Object Name
{
int i = 0;
char ch;
while ((ch = fgetc (bin3ds)) != 0)
{
objectname [i] = ch;
i++;
}
objectname [i] = '\0';
}
case 0x4110: //Vertices List
{
fread (&nvertices, sizeof (WORD), 1, bin3ds);
fread (&listvertices, sizeof (float), nvertices, bin3ds);
}
case 0x4140: //U And V Coordinates
{
fread (&listuvcoord, sizeof (float), (nvertices*2), bin3ds);
}
}
}
fclose (bin3ds);
return 0;
}
///////////////////////////////////////////////////////////////////
int main (void)
{
printf ("%s", listvertices);
while (1)
{
}
return 0;
}
La fonction MAIN est juste là pour tester mon programme, par exemple dans ce cas le programme devrait afficher les coordonnées de tout les sommets de l'objet. Mais en réalité il affiche: <null>.
Je pense que le programme ne cherche pas correctement dans le fichier, mais je ne sais pas comment corriger l'erreur. Si vous pouviez m'aider, ce serait super.
Thanks.