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 :

problème de lecture de fichier binaire [fortran/C]


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Singapour

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 6
    Points
    6
    Par défaut problème de lecture de fichier binaire [fortran/C]
    Bonjour à vous,

    Ca fait maintenant plusieurs semaines que je me confronte à ce problème et pour l'instant je n'ai pas encore réussi à le résoudre.

    J'ai un fichier binaire qui est structuré de la façon suivante:

    - entier
    - tableau 2D de réel
    - entier

    J'ai un programme fortran
    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
     
            program test
     
            parameter (Imax=720,Jmax=361)
     
            real VarGFS(Imax,Jmax)
            character*64 FileIn
     
            FileIn='gfs.TMP.t00z.bin'
            open(10,file=FileIn,form='unformatted')
     
            read(10) IntBin
            read(10) VarGFS
            read(10) IntBin
     
            do i=1,10
            do j=1,10
            write(*,*) VarGFS(i,j)
            enddo
            enddo
            close(10)
     
            end
    et un programme C
    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
     
    #include <stdio.h>
     
    typedef struct{
        int head;
        float val[720][361];
        int foot;
    }VarGFS;
     
    int main(){
        int i,j;
        VarGFS buffer;
        FILE* f = fopen("gfs.TMP.t00z.bin","rb");
        if(f){
            fread(&buffer,sizeof(VarGFS),1,f);
            for(i=0;i<10;i++){
                for(j=0;j<10;j++)
                    printf("%f\n",buffer.val[i][j]);
            }
        }
    }
    Ils sont censés rendre le même résultat mais non.
    Est-ce que vous avez une solution ? Ou quelque conseil qui pourrait m'aider ?

    Merci d'avance

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    En première lecture, la retranscription à l'air correcte (mais je ne connais pas le Fortran)

    Peut être un problème de différence de taille entre le "real fortran" et le "float C" ou entre "IntBin fortran" (dont on ne voit pas la déclaration) et le "int C".

    Peut être aussi un problème de padding avec ta "structure C VarGFS" (des octets rajoutés par le compilateur pour respecter des contraintes d'alignement mémoire.

    Est ce que tu peut faire afficher en C et en Fortran la taille des tes variables : sizeof(VarGFS), sizeof(int) et sizeof(float) en C mais je ne connais pas l'équivalent en Fortran pour sizeof(VarGFS) et sizeof(IntBin) ?

    Est ce que tu peux attacher le fichier "gfs.TMP.t00z.bin" (ou un petit bout s'il est trop gros) et donner les infos que tu attends dedans ?

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fread(&buffer,sizeof(VarGFS),1,f);
    Cette solution n'est pas portable : la fonction écrit tel quel dans la mémoire (dans le buffer) ce qui est contenu dans le fichier, byte par byte, sans tenir compte de la taille des types de chacun des membres de ta structure, ni de l'endianess ni de l'alignement des données ; ces trois choses peuvent varier selon les machines. Conséquence : sur telle machine tes données seront correctement copiées dans la structure et sur telle autre machine elles seront copiées "n'importe comment".

    En outre, je te conseille d'allouer dynamiquement de la mémoire pour ton tableau à deux dimensions val. Il a une taille assez conséquente, la pile risque de ne pas trop apprécier.

    Sinon, à part cela, je ne connais le Fortran que de nom. Je ne peux donc pas t'aider pour la résolution de ton problème.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Singapour

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    D'abord merci pour vos réponses.

    Pour ce qui est des tailles, tous les types ont la même taille que se soit en fortran ou en C.
    int / IntBin / float = 4
    VarGFS = 1039680

    Edit :
    Après vérification VarGFS en C est de 1039688 et en Fortran 1039680
    ce qui est logique vu qu'en C VarGFS contient 2 entiers. Mais ca ne change pas la taille du tableau de float
    voici la premiere partie du fichier gfs.TMP.t00z.bin =>ici
    le fichier original fait environ 60mo

    et voici les 100 premiers résultats attendus
    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
    101
     
       238.30000    
       237.10001    
       235.60001    
       233.80000    
       231.70000    
       230.10001    
       229.20000    
       228.60001    
       227.90001    
       227.30000    
       238.30000    
       237.10001    
       235.60001    
       233.80000    
       231.70000    
       230.10001    
       229.20000    
       228.50000    
       227.80000    
       227.30000    
       238.30000    
       237.10001    
       235.60001    
       233.80000    
       231.70000    
       230.10001    
       229.10001    
       228.50000    
       227.70000    
       227.20000    
       238.30000    
       237.10001    
       235.60001    
       233.80000    
       231.70000    
       230.10001    
       229.10001    
       228.40001    
       227.70000    
       227.10001    
       238.30000    
       237.10001    
       235.60001    
       233.80000    
       231.80000    
       230.10001    
       229.00000    
       228.30000    
       227.60001    
       227.10001    
       238.30000    
       237.00000    
       235.60001    
       233.80000    
       231.80000    
       230.10001    
       229.00000    
       228.30000    
       227.60001    
       227.00000    
       238.30000    
       237.00000    
       235.60001    
       233.80000    
       231.80000    
       230.10001    
       228.90001    
       228.20000    
       227.50000    
       226.90001    
       238.30000    
       237.00000    
       235.60001    
       233.80000    
       231.80000    
       230.10001    
       228.90001    
       228.20000    
       227.50000    
       226.90001    
       238.30000    
       237.00000    
       235.60001    
       233.80000    
       231.80000    
       230.10001    
       228.80000    
       228.10001    
       227.40001    
       226.80000    
       238.30000    
       237.00000    
       235.60001    
       233.80000    
       231.80000    
       230.10001    
       228.80000    
       228.00000    
       227.40001    
       226.70000
    Au départ j'ai un programme fortran (qui fonctionne) et on m'a demandé de le retranscrire en C. Ce n'est pas grave si vous ne connaissez pas le fortran car moi non plus =)

    Je vais essayer d'allouer dynamiquement comme jeroman me le conseille mais je doute que ca soit une solution dans mon cas car ce n'est pas un tableau de 720*361 mais une centaine que je dois traiter.

    En tout cas merci de m'aider.

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    En regardant ton fichier en binaire, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Ý<SI><NUL><NUL>€lC<NUL>€lC<NUL>€lC<NUL>€lC<NUL>€lC...
    pendant très longtemps au début (au moins une centaine de valeurs).

    Si on fait abstraction du problème de représentation des float entre C et fortran et du problème de boutisme des nombres, cela représente quand même toujours les mêmes valeurs. C'est ce qu'indique le programme chez moi (j'ai ajouté l'affichage de la valeur du header et du footer), il me donne :

    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
    head=1039680
    foot=1039680
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000
    236.500000

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Singapour

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Oui je pense que ton résultat est normal.

    Pour info cela représente des températures en °K et je passe les détails mais les premières valeurs indique la température en antarctique donc si tu fais la conversion on est à -36°C, ca semble correct.

    ce que tu trouves dans head et foot est le nombre de valeurs dans le tableau (720*361*sizeof(float)), ces valeurs ne me servent pas.

    Ensuite je viens de voir que le fortran gérait les tableaux par lignes au contraire du C qui les gère en colone, c'est peut-etre là qu'est la différence.

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Si j'inverse ligne et colonne, cela donne ceci :
    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
    101
    102
    head=1039680
    foot=1039680
    236.500000
    236.500000
    235.600006
    236.900009
    234.600006
    237.300003
    232.900009
    238.000000
    230.800003
    239.199997
    236.500000
    236.500000
    235.600006
    236.900009
    234.600006
    237.400009
    232.900009
    238.000000
    230.800003
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.600006
    237.400009
    232.900009
    238.000000
    230.800003
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.600006
    237.400009
    232.900009
    238.000000
    230.900009
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.600006
    237.400009
    232.900009
    238.000000
    230.900009
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.500000
    237.400009
    232.800003
    238.100006
    230.900009
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.500000
    237.500000
    232.800003
    238.100006
    230.900009
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.500000
    237.500000
    232.800003
    238.100006
    230.900009
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.500000
    237.500000
    232.900009
    238.100006
    230.900009
    239.300003
    236.500000
    236.500000
    235.600006
    236.900009
    234.500000
    237.500000
    232.900009
    238.100006
    231.000000
    239.400009

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Singapour

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    C'est bon le problème est réglé !
    C'était juste un histoire d'équation mal formulée.
    Il n'y a aucun problème de typage, ni d'alignement, ...

    Je vous remercie pour votre aide =)

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

Discussions similaires

  1. Problème de lecture de fichiers binaires
    Par -Gesicht- dans le forum Débuter
    Réponses: 7
    Dernier message: 05/07/2013, 17h15
  2. probléme lecture de fichier binaire octer par octet
    Par ousmanesidibe dans le forum C++
    Réponses: 2
    Dernier message: 12/12/2009, 21h34
  3. [Fortran 95] Problème de lecture de fichier
    Par hammah dans le forum Fortran
    Réponses: 3
    Dernier message: 08/02/2009, 02h06
  4. Lecture de fichier binaire fortran avec java
    Par bigbrother737 dans le forum Langage
    Réponses: 1
    Dernier message: 11/05/2007, 10h34
  5. Réponses: 5
    Dernier message: 26/03/2007, 01h30

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