Bonjour,
Existe-t-il une fonction qui permet de lire 10 bits d'un coup ou suis-je obligé de lire un nombre de byte entier ?
Merci
Version imprimable
Bonjour,
Existe-t-il une fonction qui permet de lire 10 bits d'un coup ou suis-je obligé de lire un nombre de byte entier ?
Merci
Que faut-il entendre par lire ? Lire dans un fichier ? Dans ce cas, oui il faut lire un nombre entier d'octets.Citation:
qui permet de lire 10 bits d'un coup
non tu ne peut pas si tu lis un fichier du doit le lire octet par octet (byte par byte)
Ce que tu peux faire, c'est lire 80 bits à la fois : tu lis un nombre entier d'octets, et un nombre entiers de bloc de 10 bits.
Ensuite, à ce champ de 80 bits, tu appliques des masques te permettant de récupérer un des 8 blocs de 10 bits.
Appliquer un masque consiste à effectuer un opération logique entre un nombre (celui à transformer) et un autre (le masque) afin de faire une opération sur les bits.
Dans ton cas, l'opération est de garder le n-ième bloc de 10 bits. Tu peux y parvenir en utilisant comme opération logique le 'et' (AND), et comme masque un nombre dont tous les bits sont à 0 sauf ceux correspondant à ceux que tu veux garder dans le premier nombre. Je ne suis pas sûr d'être très clair...
Prenons un exemple (bit de poids faible à droite).
Tu as le champ de bits suivant : 0100101110101011 (16 bits)
et tu veux le premier champ de 4 bits. Tu effectues le masquage :
0100101110101011 AND 1111000000000000
Tu obtiens: 0100000000000000
Divises ce résultat par 2^12 et tu as le premier champ de 4 bits (12 = 4 * 3, 4 = taille du champ de bits, 3 = indice du champ de bits que tu veux en commencant par la droite(=poids faible) ou 3 = nombre de champs de 0 à enlever)
Si maintenant tu veux récupérer le 2e champ de 4 bits :
0100101110101011 AND 0000111100000000
Tu obtiens : 0000101100000000
Ensuite tu divises par 2^8 et tu obtiens 1011
Ca a l'air assez flou ce que je dis, j'espère que tu as compris.
Si tu n'as pas d'autres questions à ce sujet, pense au bouton :resolu:
tu peut lire un nombre de bit desire si tu utilise la fonction read de unistd sur les systeme unix je connais pas si elle est portable sur windows.
prototype:
ssize_t read(int fd, void *buf, size_t count);
fd: file descriptor (valeur de retour de open)
buf: ou tu stocke ton mot
count: nombre d'octet a lire
la fonction retourne le nombre d'octet lu[/b]
ce qu lit des octets, pas des bits... :roll:
Strab: Bonne idée en effet (même si lire par séries de 40 bits devrait être plus facile: 40 est le plus petit multiple commun de 8 et 10)
Gné ? Qu'est-ce qui ne va pas avec fread() ?Citation:
Envoyé par Meyn
<ironiePasMechante>Excellente idée ! On veut en lire 10 donc on en lit 80 d'un coup et hop! Le problème est résolu !</ironiePasMechante>Citation:
Envoyé par Strab
Et sur une machine 32bits, tu fais comment pour appliquer un masque à un champ de 80 bits ? Mmmh ?Citation:
Envoyé par Strab
Là, il y a du bon. Effectivement, à un moment ou à l'autre il va falloir faire un 'et' logique.Citation:
Envoyé par Strab
Stop ! Je croyais que tu avais dit 80 ! Tu triches !Citation:
Envoyé par Strab
Juste un poil, mais il y a de l'idée.Citation:
Envoyé par Strab
Bon, on y va ?Je ne prétends pas que c'est parfait, mais c'est un bon début.Code:
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 [dschris@ads.doubleclick.net tmp]$ cat bitRead.c #include <stdio.h> #include <limits.h> /* pour CHAR_BIT */ #include <stdlib.h> #define BIT_READ_ERROR 0xff typedef struct { unsigned long charOffset; unsigned char bitOffset; unsigned char currentChar; FILE *file; } bitFile; bitFile *bfopen(const char *name,const char *mode); int bfclose(bitFile *bf); unsigned char bfreadbit(bitFile *bf); bitFile *bfopen(const char *name,const char *mode) { bitFile *bf=NULL; if (!(bf=malloc(sizeof(bitFile)))) return NULL; if (!(bf->file=fopen(name,mode))) { free(bf); return NULL; } bf->charOffset=0UL; bf->bitOffset=0; bf->currentChar=0; return bf; } int bfclose(bitFile *bf) { int r=fclose(bf->file); free(bf); return r; } unsigned char bfreadbit(bitFile *bf) { unsigned char r; if (bf->bitOffset==0) { if (!fread(&(bf->currentChar),1,1,bf->file)) { return -1; } } r=( bf->currentChar >> ( CHAR_BIT - 1 - bf->bitOffset ) ) & 0x1; bf->bitOffset++; if (bf->bitOffset==CHAR_BIT) { bf->bitOffset=0; bf->charOffset++; } return r; } int main(int argc, char *argv[]) { int returnValue=EXIT_SUCCESS; /* until proven false */ bitFile *bf; unsigned long bitOffset; unsigned char bit; if (argc!=3) { fprintf(stderr,"Usage: %s <fileName> <countOfBitsToRead>\n",argv[0]); return EXIT_FAILURE; } if (!(bf=bfopen(argv[1],"rb"))) { fprintf(stderr,"error: couldn't open bitfile\n"); return EXIT_FAILURE; } for (bitOffset=0;bitOffset<strtoul(argv[2],NULL,10);bitOffset++) { if ((bit=bfreadbit(bf))==BIT_READ_ERROR) { fprintf(stderr,"error: bfread() failed\n"); returnValue=EXIT_FAILURE; break; } printf("%i",bit); } printf("\n"); bfclose(bf); return returnValue; } [dschris@ads.doubleclick.net tmp]$ gcc -Wall -o bitRead bitRead.c [dschris@ads.doubleclick.net tmp]$ echo -ne "\x01\x80" > bitReadTestFile.bin [dschris@ads.doubleclick.net tmp]$ ./bitRead bitReadTestFile.bin 10 0000000110 [dschris@ads.doubleclick.net tmp]$
Exercices :
1) écrire une fonction dont le prototype serait "unsigned long bfreadNBits(bitFile *bf,unsigned char count);" (ou similaire) renvoyant un unsigned long dont les <count> bits de poids faible sont les <count> bits lus depuis le "bitFile" passé en paramètre ;
2) écrire les équivalents des fonctions fseek, fgetpos, fsetpos, ftell et rewind pour un "bitFile" (indice : la création d'un type "bitOffset" représentant la position d'un bit dans le fichier et la modification de "bitFile" en conséquence peuvent aider, ne serait-ce qu'à rendre le code plus clair [1]) ;
3) définir un type "bitBuffer" permettant de manipuler des bits en mémoire et les fonctions associées ("bbmalloc()", "bbrealloc()", "bbfree()", sans oublier "bbpeek()" et "bbpoke()" permettant de lire/écrire 1 bit dans le "bitBuffer") ;
4) écrire la fonction "bfwritebit()" en faisant en sorte qu'elle permette aussi d'écrire 1 bit en plein milieu du fichier (après un "bfseek()" par exemple).
Oui, il faut y penser.Citation:
Envoyé par Strab
[1] : penser qu'un fichier de 4 milliards d'octets contient CHAR_BIT*4 milliards de bits, ce qui est un nombre assez grand et ne pourra peut-être pas (je vous laisse calculer) être stocké dans un "unsigned long" sur beaucoup de plate-formes...