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 d'un fichier binaire


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Points : 17
    Points
    17
    Par défaut lecture d'un fichier binaire
    Bonjour à tous,

    je travaille actuellement sur un programme C qui prends en entrée un fichier binaire issu de fortran (créé avec un write(... form = 'unformatted')) qui contient un tableau de flottants de dimension 9000*9000.

    Je me suis renseigné ici, ici et mais j'ai du mal à voir ce que je vais obtenir une fois le fichier ouvert:
    une fois que j'aurai ouvert le fichier avec un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FILE * fichier;
    fichier = fopen( "monfichier", "rb");
    j'aurai bien un flux se rapportant au fichier concerné, sachant que je veux recuperer des flottants uniquement y a-t-il possibilité de les récupérer directement (j'entends par là sans avoir à passer par une chaine de caractère à caster en flottants ensuite)?

    j'ai pensé utiliser fseek, celà vous semble-t-il correct?

    Merci d'avance.

  2. #2
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Bonjour,
    Ton fichier ne contient pas des chaîne de caractères, ou des flottants, ou autres. Il contient des octets.
    Si tu es certain que ces octets correspondent à des flottants, et que la représentation des flottants est identique en C et en Fortran (désolé, je ne connais pas le Fortran), alors tu peux lire les X octets correspondants à un flottant, et les stocker directement dans ta variable de type flottant.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Points : 17
    Points
    17
    Par défaut
    question bête comment connaît-on le nombre d'octets sur lequel est codé une variable?

    Donc je peux utiliser fseek?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fseek( FILE *monfichier, long le_nombre_d'octets, int position);
    ça me chiffone un peu fseek retourne un int non?

    le code fortran sort des valeurs de ce type: -0.100009274483E+01
    Un flottant n'est pas aussi précis, le type double suffira-t-il?

  4. #4
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    question bête comment connaît-on le nombre d'octets sur lequel est codé une variable?
    Utilise la fonction sizeof qui retourne le nombre d'octets.
    ex: octets = sizeof(double) -> 8 octets dans mon implémentation


  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Il faut que tu saches si tes flottants sont des simple (REAL*4 =C float) ou des double (REAL*8=C double) précisions (je ne plus sur de la syntaxe fortran). Si l'écriture a eu lieu sur la même machine, tu vas pouvoir lire ton tableau en faisant quelque chose du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int rowcount = 9000;
    int colcount = 9000;
    typedef double real; /* ou typedef float real; */
    real *table = malloc(rowcount*colcount*sizeof(real));
    if (fread(table, sizeof(real), rowcount*colcount, fp) != rowcount*colcount) {
       /* traitement de l'erreur */
    }
    Et alors tu peux accéder à tes éléments avec: table[c*rowcount+l] (note Fortran stocke les matrices transposées par rapport à l'usage C).

  6. #6
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par booby
    Donc je peux utiliser fseek?
    Attention, fseek ne sert pas à lire des données dans le fichier, mais à s'y déplacer !

  7. #7
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    ça me chiffone un peu fseek retourne un int non?
    Prototype de la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int fseek( FILE *stream, long depl, int posit);
    Valeurs renvoyées:
    -> 0 si déroulement correct
    -> sinon une valeur non nulle est renvoyée. Exemple d'erreur: le flux n'a pas été ouvert.

    Ca te permet de tester la réussite de ton positionnement dans le fichier et non de te retourner ton float ou double etc...
    Il te faudra faire une lecture avec fread().

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Points : 17
    Points
    17
    Par défaut
    ok, merci pour vos réponses, je teste ça et je vous tiens au courant.

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par booby
    question bête comment connaît-on le nombre d'octets sur lequel est codé une variable?
    En C, on ne parle pas d'octets mais de char. Un char fait au moins 8 bits. Il fait exactement CHAR_BIT (défini dans <limits.h>).

    sizeof retourne la taille d'un objet ou d'un (type) en nombre de char.

    En combinant astucieusement ces informations, tu peux savoir combien de bits il y a dans un objet ou un type.

    Mais attention, à part dans les [[un]signed] char, tous les bits ne sont peut être pas utilisables. Une certaine combinaison de bits pourrait très bien être une 'trap representation' et donc être invalilde. C'est pourquoi la plage des valeurs possibles d'un type est définie par des macros telles que INT_MIN, ULONG_MAX, toutes définis dans <limits.h>, indépendamment du nombre de bits d'un type.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int rowcount = 9000;
    int colcount = 9000;
    typedef double real; /* ou typedef float real; */
    real *table = malloc(rowcount*colcount*sizeof(real));
    if (fread(table, sizeof(real), rowcount*colcount, fp) != rowcount*colcount) {
       /* traitement de l'erreur */
    }
    Et alors tu peux accéder à tes éléments avec: table[c*rowcount+l] (note Fortran stocke les matrices transposées par rapport à l'usage C).
    ok, en regardant d'un peu plus pres pour adapter ça à mon code, je me suis aperçu que quelques subtilités m'échappent ;-):

    sauf erreur de ma part, table est censé receuillir les nombres lus dans le fichier. Ce que je ne comprends pas c'est la ligne de test qui suit l'allocation mémoire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (fread(table, sizeof(real), rowcount*colcount, fp) != rowcount*colcount)
    que teste-t-on exactement?
    il me semble qu'à ce moment table est "vide" non? (je ne pense pas avoir compris comment le remplir :-( )

  11. #11
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (fread(table, sizeof(real), rowcount*colcount, fp) != rowcount*colcount)
    La fonction fread lit "rowcount*colcount" éléments (de taille "sizeof(real)" chacun) dans le fichier décrit par "fp" et les stocke dans le tableau "table".
    Le test sert à vérifier que tous les éléments attendus ont bien été lus.

  12. #12
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    que teste-t-on exactement?
    il me semble qu'à ce moment table est "vide" non? (je ne pense pas avoir compris comment le remplir :-( )
    On teste le retour de la fonction fread() au nombre d'éléments lus. Faut jeter un coup d'oeil au prototype de la fonction!

    C'est l'équivalent de cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int octetsLus = 0;
     
    octetsLus = fread(table, sizeof(real), rowcount*colcount, fp);
    if (octetsLus != rowcount*colcount)
    {
       /*traitement de l'erreur*/
    }

  13. #13
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par homeostasie
    C'est l'équivalent de cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int octetsLus = 0;
     
    octetsLus = fread(table, sizeof(real), rowcount*colcount, fp);
    if (octetsLus != rowcount*colcount)
    {
       /*traitement de l'erreur*/
    }
    Euh... ben en fait non, ou alors le nom de ta variable est mal choisi
    fread et fwrite renvoient le nombre d'éléments correctement lus ou écrits (et non pas le nombre d'octets).

  14. #14
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par zooro
    Euh... ben en fait non, ou alors le nom de ta variable est mal choisi
    champsLus ...

  15. #15
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    Euh... ben en fait non, ou alors le nom de ta variable est mal choisi
    Oui...Le nom de la variable est mal choisi! Sorry.

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par zooro
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (fread(table, sizeof(real), rowcount*colcount, fp) != rowcount*colcount)
    La fonction fread lit "rowcount*colcount" éléments (de taille "sizeof(real)" chacun) dans le fichier décrit par "fp" et les stocke dans le tableau "table".
    Le test sert à vérifier que tous les éléments attendus ont bien été lus.
    ok, donc cette ligne fait deux opérations d'un coup!... vachement bien fait tout de même.

    Merci encore de vous etre penchés sur mon problème, j'essaie et vous tiens au courant.

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par booby
    ok, donc cette ligne fait deux opérations d'un coup!... vachement bien fait tout de même.
    C'est fread() qui fait ça (lecture par blocs), et je ne vois pas comment elle pourrait faire autrement...

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Points : 17
    Points
    17
    Par défaut
    ok, tres bien, ça marche! merci à tous pour votre aide! chapeau!

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

Discussions similaires

  1. Lecture d'un fichier Binaire
    Par insa59 dans le forum C
    Réponses: 10
    Dernier message: 06/03/2007, 19h18
  2. Réponses: 1
    Dernier message: 21/12/2006, 13h06
  3. lecture d'un fichier binaire
    Par Tonta dans le forum C++
    Réponses: 1
    Dernier message: 14/04/2006, 06h53
  4. lecture d'un fichier binaire en VB
    Par olivier] dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 28/12/2005, 11h17
  5. Lecture d'un fichier binaire
    Par Gloubie dans le forum Langage
    Réponses: 9
    Dernier message: 05/12/2005, 12h51

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