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 :

lecture fichier binaire de double


Sujet :

C

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut lecture fichier binaire de double
    Bonjour,
    Ma question fait suite à une discussion précédente concernant la lecture d'un fichier binaire.

    Voilà, je voudrais lire un fichier binaire (une image codée 64 bits, PC_REAL).
    J'ai suivi les conseils donnés dans une autre discussion, j'ai fait une lecture comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int im_size = 128*128;
    int n;
    double *buff;
    buff = malloc(im_size*sizeof(double));
    if((n=fread(buff,sizeof(double),img_size,fdFic)) != img_size) {
    	/* traitement de l'erreur */		
    }
    /* après avoir ouvert fdFic en mode 'rb' */
    Mais lorsque j'affiche la première valeur du buffer par exemple, en hexa pour comparer avec les données de mon fichier lu avec un éditeur hexa, je m'aperçoit que ça lit un peu n'importe comment!
    Les lignes de code sont les suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *toto;
    toto = (char *)&buff[0];
    printf("toto: %x %x %x %x %x %x %x %x\n", toto[0], toto[1], toto[2], toto[3], toto[4], toto[5], toto[6], toto[7]);
    printf("buff: %e\n", buff[0]);
    A l'affichage, ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    toto: ffffffdf fffffff9 4b ffffffb4 21 ffffffde 15 3e
    buff: -2.119751e+154
    Au lieu de donner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    toto: df f9 4b b4 21 de 15 3e!!!
    Je ne vois pas du tout comment résoudre ce problème, ça fait un moment que je cherche et ne trouve point d'erreur.

    Quelqu'un aurait-il une idée?

    Merci d'avance!
    Sandra

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Les char sont apparemment signes sur ta plateforme et donc tu vois une extension de signe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned char *toto = (unsigned char*)&buffer;

  3. #3
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    Effectivement, ça résoud le problème de l'affichage de toto! Merci. Ca m'a permis de vérifier que je lisais bien ce que j'avais dans le fichier.

    Par contre, je ne comprends pas la valeur de buff

    En effet, je voudrais chercher par la suite le max et le min de l'image, pour cela je fais une boucle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    double *max=0;
    double *min=1000000000;
     
    for (i=0;i<im_size;i++){
     
    	if (buff[i] < *min)
    	     *min = buff[i];
    	     printf("min, i: %1.7e , %d\n",*min, i);
    	if (buff[i] > *max)
    	     *max = buff[i];
    	printf("max, i: %1.7e , %d\n\n",*max, i);
    }
    Mais les valeurs trouvées sont complètement fausses, je trouve:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    min: -1.7188562e+308
    max: 1.7898213e+308!!
    C'est pour cela que j'avais chercher à afficher les valeurs en hexa de buff avec toto pour savoir si je lisais bien le fichier

    Aurais-tu une idée de l'origine de l'erreur?
    Sandra

  4. #4
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par sandra771
    double *max=0;
    double *min=1000000000;
    Attention, tu es entrain d'initialiser des pointeurs sur des doubles !!!!

  5. #5
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    En fait, j'ai fait un raccourci, c'est pas vraiment ça que je fais.
    Le code complet:

    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
    /* Fonction */
    void minmax(double *buff,int len,
    		double *min, double *max){
     
    	int i;
    	*max=0;
    	*min=100000000;
    	unsigned char *toto;
     
    	for (i=0;i<len;i++){
     
    	     toto = (unsigned char *)&buff[i];
    	     printf("toto: %x %x %x %x %x %x %x %x\n", toto[0], toto[1], toto[2], toto[3], toto[4], toto[5], toto[6], toto[7]);
    	     printf("buff, i: %e, %d\n", buff[i], i);
     
    	     if (buff[i] < *min)
    		     *min = buff[i];
    		     printf("min, i: %1.7e , %d\n",*min, i);
    	     if (buff[i] > *max)
    		     *max = buff[i];
    		     printf("max, i: %1.7e , %d\n\n",*max, i);
    	     }
    }
     
     
    int main(int argv, char* argc []) {
     
    	double *buff;
    	int img_size;
                 double min; 
    	double max;
    	int i,n;
    	FILE *fdFic;
     
     
    	if (argv != 3) { 
    		/* traitement d'erreur */
    	}
     
     
    	if ((img_size = atoi(argc[1]))==0) { 
                            /* traitement d'erreur */
    	}
                 printf("img_size: %d\n", img_size);
     
    	printf("filename: %s\n", argc[2]);
    	if ((fdFic=fopen(argc[2],"rb"))==NULL)
                {
    		/* traitement d'erreur */
    	}
     
    	buff= malloc(img_size*sizeof(double));	
    	if((n=fread(buff,sizeof(double),img_size,fdFic)) != img_size) 
                 {
    		/* Traitement d'erreur */	
                 }
     
                 /* Appel de la fonction de recherche min et max */	
    	minmax(buff,img_size,&min,&max);	
    	printf("%1.7e \n%1.7e\n",min,max);
     
    	free(buff);
    	fclose(fdFic);
     
    return 0;
    }
     
    /* On passe en paramètres la taille de l'image et le nom du fichier */
    Voilà!

  6. #6
    Membre habitué
    Inscrit en
    Novembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 12
    Par défaut
    Ca y est, je pense avoir trouvé la solution au problème... reste à expérimenter
    En fait, j'essayais d'afficher mon buffer en double IEEE alors que le format de double de mon image est en PC-REAL, qui inverse tous les octets!
    Il faut donc que j'inverse tous les octets avant de l'afficher en double...

  7. #7
    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 sandra771
    Ca y est, je pense avoir trouvé la solution au problème... reste à expérimenter
    En fait, j'essayais d'afficher mon buffer en double IEEE alors que le format de double de mon image est en PC-REAL, qui inverse tous les octets!
    Il faut donc que j'inverse tous les octets avant de l'afficher en double...
    Même pas sur que ça marche. Le format des flottants du C n'est pas spécifié par la norme. Il dépend de l'implémentation.

    Pour être correct, il va falloir faire un conversion manuelle en manipulant des bits dans une variable unsigned long long... (C99) Il faut la spécification détaillée des doubles PC-REAL et de ceux de ton implémentation. (<float.h> peut aider...)

    Ca va être chaud, et il va y avoir des pertes de données...

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/06/2011, 11h43
  2. Lecture fichier binaire et inversion d'octets
    Par zoro_le_renard dans le forum Fortran
    Réponses: 8
    Dernier message: 17/07/2007, 20h35
  3. Réponses: 5
    Dernier message: 02/10/2006, 22h54
  4. Lecture fichier binaire
    Par kek_net dans le forum Langage
    Réponses: 5
    Dernier message: 07/08/2006, 19h37
  5. Lecture fichier binaire
    Par gabule dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 30/05/2006, 15h53

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