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 :

conversion de bit en int, float, char, etc.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut conversion de bit en int, float, char, etc.
    Bonjour.
    Je dois lire des données dans un fichier de type binaire, et en extraire des informations à convertir en int, float ou char et les stocker dans une structure. Le problème c'est que je n'ai aucune idée de comment convertir par exemple 4 bytes en un int...

    Concrètement, j'ai un fichier avec des entrées de 50 bytes chacune (les entrées sont identiques).
    Les 4 premiers bytes représentent un int*,
    les 7 bytes de 8 à 14 des char,
    les bytes 18 à 21 sont un float*,
    de 30 à 37 des char,
    puis bytes 40 à 42 3 char...

    Grosso modo je veux lire le fichier, obtenir pour chaque entrée les 5 informations ci-dessus pour après les stocker dans une structure...
    Avez-vous une idée de comment je dois m'y prendre? Pour le moment, je sais seulement que fread permet de lire les fichiers mais je connais pas les opérations sur les bytes pour les convertir en types primitifs (char, int, etc...)...
    Merci d'avance !

    PS: j'ai essayé de mettre en PJ le fichier mais je crois que ce n'est pas possible de mettre des fichiers binaires...

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Il suffit de lire les informations les unes après les autres :

    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
    int * param_1;
    char param_2[7];
    float * param_3;
     
    /* on s'assure que les types font bien la taille attendue */
    ASSERT(4 == sizeof param_1);
    ASSERT(7 == sizeof param_2);
    ASSERT(4 == sizeof param_3);
     
    /* ouverture du fichier */
    FILE *f = fopen("..." , "rb");
     
     
    if(NULL == f) {
        perror("...");
    } else {
        /* lecture des paramètres */
        fread(&param_1, sizeof param_1, 1, f);
     
        fread(param_2, sizeof *param_2, 7, f);
     
        fread(&param_3, sizeof param_3, 1, f);
    }
    Attention,
    • je ne tiens pas compte de l'endianness ici.
    • Un int* sortit de son contexte ne sert pas à grand chose, ne sommes nous pas devant un cas d'un tableau mal enregistré dans un fichier ?
    • Les format d'échanges binaires sont souvent source de problème, il ne faut pas hésiter à utiliser du format texte.


    On pourrait aussi faire en une fois avec une structure. Mais dans ce cas là, on s'expose aux problèmes d'alignement qui n'est pas forcement les mêmes d'un compilateur à l'autre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct params {
        int * p_1;
        char p_2[7];
        float * p_3;
    };
     
    struct params mes_params;
    fread(&mes_params, sizeof mes_params, 1, f);

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut
    Citation Envoyé par mabu Voir le message
    Bonjour,

    Il suffit de lire les informations les unes après les autres :

    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
    int * param_1;
    char param_2[7];
    float * param_3;
     
    /* on s'assure que les types font bien la taille attendue */
    ASSERT(4 == sizeof param_1);
    ASSERT(7 == sizeof param_2);
    ASSERT(4 == sizeof param_3);
     
    /* ouverture du fichier */
    FILE *f = fopen("..." , "rb");
     
     
    if(NULL == f) {
        perror("...");
    } else {
        /* lecture des paramètres */
        fread(&param_1, sizeof param_1, 1, f);
     
        fread(param_2, sizeof *param_2, 7, f);
     
        fread(&param_3, sizeof param_3, 1, f);
    }
    Dans ce cas, comme dans celui de la structure, j'imagine qu'on suppose que les informations se succèdent?... C'est à dire qu'après avoir lu le premier int*, les bytes suivant sont les 7 char. Or dans mon cas, les byte 1 à 4 sont le int*, puis c'est dans les bytes 7 à 14 qu'il y a des char puis encore 2 bytes "vides", etc... Le format text de ce que je veux lire est:
    1|AtulBat|4.8281|9MCS8255|34.4

    Citation Envoyé par mabu Voir le message
    Attention,
    • je ne tiens pas compte de l'endianness ici.
    • Un int* sortit de son contexte ne sert pas à grand chose, ne sommes nous pas devant un cas d'un tableau mal enregistré dans un fichier ?
    • Les format d'échanges binaires sont souvent source de problème, il ne faut pas hésiter à utiliser du format texte.
    J'ai pas bien compris de quoi s'agissait l'endianness, je regarderais ça si ce que je test ne marche pas.
    Pour le int* et le format binaire, je suis d'accord mais c'est dans le cadre d'un devoir et les formats sont imposés.

  4. #4
    Invité(e)
    Invité(e)
    Par défaut
    Dans ce cas, comme dans celui de la structure, j'imagine qu'on suppose que les informations se succèdent?... C'est à dire qu'après avoir lu le premier int*, les bytes suivant sont les 7 char. Or dans mon cas, les byte 1 à 4 sont le int*, puis c'est dans les bytes 7 à 14 qu'il y a des char puis encore 2 bytes "vides", etc...
    Oui effectivement, j'ai lu trop vite...

    Correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        int i;
        /* lecture du premier int * */
        fread(&param_1, sizeof param_1, 1, f);
     
        /* on saute X octets */
        for(i = 0; i < X; ++i) {
            fgetc(f);
        }
     
        /* lecture des char */ 
        fread(param_2, sizeof *param_2, 7, f);
    Le format text de ce que je veux lire est:
    1|AtulBat|4.8281|9MCS8255|34.4
    Mais on est bien d'accord, ton fichier est du binaire ?

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut
    Citation Envoyé par mabu Voir le message
    Oui effectivement, j'ai lu trop vite...

    Correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        int i;
        /* lecture du premier int * */
        fread(&param_1, sizeof param_1, 1, f);
     
        /* on saute X octets */
        for(i = 0; i < X; ++i) {
            fgetc(f);
        }
     
        /* lecture des char */ 
        fread(param_2, sizeof *param_2, 7, f);
    Mais on est bien d'accord, ton fichier est du binaire ?
    Ok merci. oui oui le fichier est bien en binaire, c'est juste que j'ai le résultat de la première entrée pour m'assurer que je lit bien.

    J'ai fait ce que tu m'as dit mais par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int* param_1;
     
    FILE* file = fopen("../testfiles/test1.dat","r");
    if(file){
        fread(&param_1, sizeof param_1, 4, file);
        printf("param_1: %i\n",*param_1);
    }
    J'ai un souci là. déjà dans le fread, si je comprend bien, tu stock le premier parametre dans l'@ de param_1? du coup pour accéder à la valeur pointé j'ai essayé de déréférencer et ça plante. du coup si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("param_1: %i\n",param_1);
    ca marche mais ça me renvoie une adresse mémoire et non l'int qui est pointé (ici en l'occurence c'est 1)...

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut
    Citation Envoyé par mabu Voir le message
    Oui effectivement, j'ai lu trop vite...

    Correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        int i;
        /* lecture du premier int * */
        fread(&param_1, sizeof param_1, 1, f);
     
        /* on saute X octets */
        for(i = 0; i < X; ++i) {
            fgetc(f);
        }
     
        /* lecture des char */ 
        fread(param_2, sizeof *param_2, 7, f);
    Mais on est bien d'accord, ton fichier est du binaire ?
    ps: mon programme bug au niveau du fgetc. Le faire tout seul, pas de problème mais par contre après le fread, ça plante...

  7. #7
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par ncheboi Voir le message
    J'ai fait ce que tu m'as dit mais par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fread(&param_1, sizeof param_1, 4, file);
    Non, ici tu demande à lire 4 fois des données de taille sizeof param_1, tu lis donc 4 fois trop de données.
    Relis la doc de fread.

    Citation Envoyé par ncheboi Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("param_1: %i\n",param_1);
    ca marche mais ça me renvoie une adresse mémoire et non l'int qui est pointé (ici en l'occurence c'est 1)
    Que vaut l'adresse mémoire ? Peux tu faire un dump hexadécimal des 20 premiers octets du fichier à lire ?

    Citation Envoyé par ncheboi Voir le message
    ps: mon programme bug au niveau du fgetc. Le faire tout seul, pas de problème mais par contre après le fread, ça plante...
    Que vaut X ?
    Décris le bug.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 09/05/2007, 13h35
  2. Réponses: 1
    Dernier message: 15/02/2007, 17h32
  3. Conversion int en char *
    Par Trunks dans le forum C
    Réponses: 6
    Dernier message: 18/03/2006, 16h44
  4. type d'un char* ? int, float .... ?
    Par stitch dans le forum C
    Réponses: 5
    Dernier message: 08/03/2006, 16h27
  5. [C++] Conversion de int en char* ou SetDlgItemText()
    Par lastcheper dans le forum MFC
    Réponses: 3
    Dernier message: 11/04/2005, 17h46

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