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 :

Lire des mots de 16 bits


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Points : 100
    Points
    100
    Par défaut Lire des mots de 16 bits
    Bonjour,

    je souhaite lire des mots de 16 bits dans un fichier afin de le convertir ensuite en un entier.
    Comment procéder pour lire ces bits ?

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (1 != fread(buf, 2, 1, file)) {
        perror("fread");
        ...
    }
    Attention évidemment aux problèmes d'endianness.

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

    Il faut d'abord savoir si les mots sont stockés sous forme de texte ou binaire.
    Texte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /* définition d'un entier court, de taille 16 bits sur x86 
    (cf FAQ pour plus de précisions) */
    short int i; 
    int ret;
    /* ouverture en mode texte */
    FILE * f = fopen("mon_fichier", "r");
    if(NULL == f) {
        /* gestion de l'erreur d'ouverture */
    } else {
        ret = fscanf(f, "%hd", &i);
        if(1 != ret) {
            /* gestion de l'erreur de lecture */
        }
    }
    Binaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /* définition d'un entier court */
    short int i; 
    int ret;
    /* ouverture en mode lecture binaire */
    FILE * f = fopen("mon_fichier", "rb");
    if(NULL == f) {
        /* gestion de l'erreur d'ouverture */
    } else {
        ret = fread(&i, sizeof(i), 1, f);
        if(1 != ret) {
            /* gestion de l'erreur de lecture */
        }
    }

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Points : 100
    Points
    100
    Par défaut
    Merci pour vos réponses.

    En fait je souhaite lire un fichier quelconque afin de le crypter (je souhaite donc faire des opérations sur les bits). Une lecture binaire est donc nécessaire non ?

    J'aurais aussi une autre question :
    comment faire pour des mots plus grands (eg. 512 bits) ?

  5. #5
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Citation Envoyé par oc_alex86 Voir le message
    J'aurais aussi une autre question :
    comment faire pour des mots plus grands (eg. 512 bits) ?
    Tu changes le 2 en 512...

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Points : 100
    Points
    100
    Par défaut
    Merci beaucoup

  7. #7
    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 matafan Voir le message
    Tu changes le 2 en 512...
    Le monsieur, il a dit bits, pas octets...
    Pas de Wi-Fi à la maison : CPL

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Points : 100
    Points
    100
    Par défaut
    Merci, j'avais compris

  9. #9
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 109
    Points
    109
    Par défaut
    pour lire des champs de bit si tu sais par exemple qu'il y a dans ton fichier un nombre entier sur 4 octets suivit par exemple d'un nombre entier sur 2 octets puis pour finir une chaine de caractere de 5 caracteres chacuns sur 1 octets tu peux faire des lectures de structures directement en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct myread
    {
     int first;
     short second;
     char third[5];
    } __attribute__ ((packed)) myread;
    attention quand meme selon l'architecture ou tu te trouves, les tailles des types peuvent varié, ceci n'est qu'un exemple dans le cas general.

    ensuite tu peux "lire" directement ta structure dans ton fichier si les bits sont cote à cote sans separateur evidement.

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    myread test;
    /* définition d'un entier court */
    int ret;
    /* ouverture en mode lecture binaire */
    FILE * f = fopen("mon_fichier", "rb");
    if(NULL == f) {
        /* gestion de l'erreur d'ouverture */
    } else {
        ret = fread(&test, sizeof(test), 1, f); //d'hab pour faire ca j'utilise des appels plus bas niveau open et read, je prefere controler au plus pret ce que fais la machine, mais je pense que ca fonctionne pareil avec fopen et fread
        if(1 != ret) {
            /* gestion de l'erreur de lecture */
        }
    tu peux aussi si par exemple tu veux lire 8 bits cote à cote separement
    utilisé ce que l'on appel des bitfields
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct a_byte
    {
    unsigned int bit0:1;
    unsigned int bit1:1;
    unsigned int bit2:1;
    unsigned int bit3:1;
    unsigned int bit4:1;
    unsigned int bit5:1;
    unsigned int bit6:1;
    unsigned int bit7:1;
    } __attribute__((packed));
    le ': x' specifie au compilateur que tu ne veux utiliser que x bit sur le type definit. le packed te permet d'etre sur qu'il n'y aura pas entre les champs de bits tampons etc.
    Attention au probleme d'allignement avec ce genre d'astuce sur certaine architecture par contre.

    si tu veux plus d'informations regarde du coté des attributes possible et leur utilités, et les bitfields. Je ne garantie pas la compilation de ces codes, je les ai ecris "on the fly", je n'ai pas de compilateur C sous la main actuellement pour tester. Ce n'est cas titre d'information

  10. #10
    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 oniric Voir le message
    pour lire des champs de bit si tu sais par exemple qu'il y a dans ton fichier un nombre entier sur 4 octets suivit par exemple d'un nombre entier sur 2 octets puis pour finir une chaine de caractere de 5 caracteres chacuns sur 1 octets tu peux faire des lectures de structures directement en faisant :
    Pour de multiples raison (endianness, padding, ordre de champs de bits), rien de ceci n'est portable. A éviter.
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 109
    Points
    109
    Par défaut
    certe je l'ai bien precisé dans mon message, mais je trouve cela bien utile quand meme si le code n'a pas besoin d'etre portable sur toutes les architectures. De plus il y a moyen de rendre cela portable. Ceci n'est qu'un exemple.

  12. #12
    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 oniric Voir le message
    De plus il y a moyen de rendre cela portable.
    Non. Pas sur une architecture 16-bit ou 32-bit dure (j'en vois qui ricanent... OK) comme 68k ou PowerPC.

    Quand aux champs de bits, selon les architectures, il peuvent être totalement inversés, avoir des largeurs différentes, ce qui est infernal...
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 109
    Points
    109
    Par défaut
    dans ce cas la, c'est la lecture de bit en general qui est infernal et non portable, car que l'on utilise un champ de bit ou un short de 2 octets comme vous faites au dessus n'est pas portable non plus, dans un cas le masque pour le short sera par exemple 0xFF00 et dans un autre 0x00FF si l'on est en little ou big endian.

    Ceci n'est en rien une aggression, plutot une curiosité de ma part, car j'en viens à me poser la question aussi.
    est ce que le 1er code (qui a mes yeux mise à part le coté portabilité est plus du bricolage) est portable ? si l'on change d'archi, donc de taille de type, donc d'endianness aussi imaginons ?

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Vu sa question, j'ai l'impression que ce qui l'intéresse est la lecture de mots et pas leur interprétation. Quand il demande à lire 2 octets, il ne se soucie pas de savoir s'il s'agit d'un short (...) mais il veut seulement 2 octets. D'où le fread 'brut' avec le nombre d'octets voulus. Par contre avec une structure ou un champs de bit, là tu interprète ce que tu lis. D'où risque!

  15. #15
    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 oniric Voir le message
    est ce que le 1er code (qui a mes yeux mise à part le coté portabilité est plus du bricolage) est portable ? si l'on change d'archi, donc de taille de type, donc d'endianness aussi imaginons ?
    Pour être portable, il faut définir un format de flux (fichier, réseau) indépendant de l'architecture.

    Une manière simple est de définir le format de flux selon la norme 'réseau', c'est à dire "MSB en tête" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Entier de 16-bit :
     
    [0] octet MSB
    [1] octet LSB
    ensuite pour écrire dans le flux, on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    unsigned data = 0x1234;
     
    fputc ((data >> (8 * 1), fp); /* MSB : 0x12 */
    fputc ((data >> (8 * 0), fp); /* LSB : 0x34 */
    a la lecture, on fait le contraire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    unsigned data = 0;
     
    data |= (fgetc (fp) << (8 * 1)); /* MSB : 0x1200 */
    data |= (fgetc (fp) << (8 * 0)); /* LSB : 0x1234 */
    En fait, c'est un peu plus compliqué, car il faut surveiller EOF, mais le principe est là... On peut aussi passer par un tableau de unsigned char que l'on ecrit / lit à la main et utiliser fwrite() / fread()...

    La version 32-bit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Entier de 32-bit :
     
    [0] octet MSB
    [1] octet 
    [2] octet 
    [3] octet LSB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    unsigned long data = 0x12345678;
     
    fputc ((data >> (8 * 3), fp); /* MSB : 0x12 */
    fputc ((data >> (8 * 2), fp); /*     : 0x34 */
    fputc ((data >> (8 * 1), fp); /*     : 0x56 */
    fputc ((data >> (8 * 0), fp); /* LSB : 0x78 */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    unsigned long data = 0;
     
    data |= (fgetc (fp) << (8 * 3)); /* MSB : 0x12000000 */
    data |= (fgetc (fp) << (8 * 2)); /*     : 0x12340000 */
    data |= (fgetc (fp) << (8 * 1)); /*     : 0x12345600 */
    data |= (fgetc (fp) << (8 * 0)); /* LSB : 0x12345678 */
    Pas de Wi-Fi à la maison : CPL

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

Discussions similaires

  1. Comment lire des fichiers iso sous Windows 7 64 bits ?
    Par Battosaiii dans le forum Windows 7
    Réponses: 8
    Dernier message: 25/02/2010, 13h44
  2. Réponses: 2
    Dernier message: 07/05/2009, 09h47
  3. Réponses: 2
    Dernier message: 28/03/2008, 18h24
  4. Réponses: 1
    Dernier message: 02/05/2007, 09h22
  5. lire mots de 10 bits
    Par calavera dans le forum C
    Réponses: 7
    Dernier message: 01/11/2005, 18h57

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