Partage
  • Partager sur Facebook
  • Partager sur Twitter

Comment lire un bit dans un fichier?

Sujet résolu
24 juillet 2007 à 18:28:55

salut tout le monde, j'aurais voulu savoir quand on ouvre un fichier en lecture binaire, comment on peut lire un bit (et je dis bien un bit et non un octet) avec fread par exemple.
En fait je voudrais faire ça pour faire un petit script de compressage (sans prétention, juste pour voir comment faire), et mon idée est de lire le fichier bit par bit et si par exemple on a 3 bit 1 à la suite dans le fichier de destination j'ecrirai 31 au lieu de 111 par exemple.

Mais si ce n'est aps comme ça que je devrais faire est-ce que vous pourriez me mettre sur la piste?

Merci d'avance

PS => j'ai une petite question à part: pourquoi quand on écrit dans un fichier en écriture binaire, on ne peut pas lire le fichier avec un éditeur normal?
  • Partager sur Facebook
  • Partager sur Twitter
24 juillet 2007 à 18:37:33

Alors la mauvaise nouvelle :
On ne peut pas lire/ecrire un seul bit dans un fichier.
Il faut toujours lire au moins un octet.

Cependant, tu as raison : les logiciels de compression descendent au niveau du "bit" pour compresser au maximum.

Mais ils passent par un buffer en RAM pour ça.
Quand ils lisent un fichier : ils lisent des octets, puis, une fois en RAM, recuperent les bits avec des masques et des opérateurs comme il faut (& | << >> ~)

Pour écrire un fichier bit par bit : prévois toi un petit buffer en RAM, ajoute tes bits dans ce buffer avec les memes opérateurs, puis, quand ton buffer (qui par hasard fait un nombre rond en octets) est plein, tu l'écris sur le disque.

Sinon, pour ta question d'apres :
Parce qu'en binaire, tu peux avoir tous les codes ASCII possibles, de 00 à FF, et qu'au format texte, certaines de ces données sont réservées, et si elles sont écrites en tant que texte, le notepad les interpretera comme des retour a la ligne (caracteres 0x0D et 0x0A) ou autres trucs comme ça :)

Il te faut un éditeur Hexa pour bien lire un fichier binaire.
  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

24 juillet 2007 à 20:47:23

Ok merci pour tes réponses, par contre je ne vois pas exactement comment faire un buffer en RAM, est-ce que tu pourrais m'en dire un peu plus sur la façon de procèder?

Merci d'avance
  • Partager sur Facebook
  • Partager sur Twitter
24 juillet 2007 à 21:02:49

Citation : The BasheR

Ok merci pour tes réponses, par contre je ne vois pas exactement comment faire un buffer en RAM, est-ce que tu pourrais m'en dire un peu plus sur la façon de procèder?

Merci d'avance


c'est une variable simple.
  • Partager sur Facebook
  • Partager sur Twitter
24 juillet 2007 à 21:18:42

Ok mais serait il possible d'avoir un exemple simple de la manière de procéder pour faire ça:

"Quand ils lisent un fichier : ils lisent des octets, puis, une fois en RAM, recuperent les bits avec des masques et des opérateurs comme il faut (& | << >> ~)

Pour écrire un fichier bit par bit : prévois toi un petit buffer en RAM, ajoute tes bits dans ce buffer avec les memes opérateurs, puis, quand ton buffer (qui par hasard fait un nombre rond en octets) est plein, tu l'écris sur le disque. "

Aussi j'ai une autre question du même ordre qui me trotte dans la tête depuis quelques minutes:
Si je veux mettre tout le contenu d'un fichier (qui est assez gros => 19 000 ko) dans une variable (donc dans la RAM), quel genre de variable je dois prendre et comment je dois m'y prendre pour tout mettre dans la RAM? (c'est un peu obscur encore pour moi, et j'aimerais y voir plus clair)

Merci d'avance
  • Partager sur Facebook
  • Partager sur Twitter
24 juillet 2007 à 23:44:14

pour un buffer, tu peux simplement prendre un octet comme buffer

char buf;
et un "curseur"
int pos = 0;

quand tu vas ajouter un bit, avec des opérations de masque, tu ajoutes le bit ou il faut, puis tu fais pos++
quand pos vaut 8, alors ça veut dire que ton octet est plein : tu le fwrite dans ton fichier, et tu le remets a 0 :)

POur allouer beaucoup de mémoire contigüe (idéal pour un fichier)

char* buf = (char*)malloc(taille);
-> tu te crées unz one de la taille que tu veux.

(certains diront qu'on ne caste pas le malloc en C pure... bah...)

n'oublie pas le
free(buf); a la fin.
  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

25 juillet 2007 à 17:53:09

Donc pour le buffer de RAM j'ai compris merci :)
Par contre est-ce que tu pourrais m'en dire plus sur les opérations de masque, qui servent à "isolé" un bit de l'octet?
Et aussi en fait pour mettre 8 bits dans un octet je ne vois pas trop bien comment il faut faire: est-ce qu'il faudrait faire buf += bit; ou buf = bit; ou autre choses encore?

Sinon pour le fichier j'ai compris merci.

Et j'aurais encore une petite question: quand on a une variable char qui contient un octet, pour faire des opérations héxadécimales ou binaire avec ce char comment est-ce qu'on fait?

Merci d'avance

PS => à oui et pour avoir al taille d'un fichier il existe une fonction simple ou bien elle est dans dans une autre bibliothèque? Si oui pourrait on me dire laquelle?
  • Partager sur Facebook
  • Partager sur Twitter
26 juillet 2007 à 18:26:47

Personne ne peut m'aider?
Merci d'avance
  • Partager sur Facebook
  • Partager sur Twitter
28 juillet 2007 à 11:21:30

Toujours personne? :(
Ma question à propos de la taille d'un fichier est résolue, mais les autres ne le sont pas :(

Merci d'avance
  • Partager sur Facebook
  • Partager sur Twitter
28 juillet 2007 à 12:17:15

regarde ma page de tuto (regarde ma signature)
§ G.2.2
  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

28 juillet 2007 à 12:40:55

Merci de ta réponse, j'ai compris maintenant, et puis je viens de voir aussi un cours apprenant ça: http://209.85.135.104/search?q=cache:stfozQ3q3h8J:cplusplus.cdoc.biz/download_fichier.php%3Ff%3D2%25201%2520operateurs%252013.pdf+comment+remplir+un+nombre+int+octet+par+octet+C&hl=fr&ct=clnk&cd=19&gl=fr&client=firefox-a

Mon sujet est résolu, merci de ton aide :)
  • Partager sur Facebook
  • Partager sur Twitter
28 juillet 2007 à 17:05:54

Exemple rapide d'un dump binaire:

// bin.c
#include <stdio.h>
#include <ctype.h>

int main(int argc, char **argv)
{
  FILE *f;
  char asc[7];
  int car, pos, i;
  unsigned long int offset;
 
  if(argc != 2) {
    printf("\nUsage : %s <fichier>\n", argv[0]);
    return 1;
  }
 
  if(!(f = fopen(argv[1], "rb"))) {
    printf("\nErreur : Fichier %s absent !\n", argv[1]);
    return 2;
  }
 
  asc[6] = pos = offset = 0;

  while((car = fgetc(f)) != EOF)
  {
    if((pos = offset % 6) == 0)
      printf("%010ld  ", offset);

    for(i = 128; i; i >>= 1)
      printf("%d%s", car & i ? 1 : 0, i == 1 ? "  " : "");

    if(isprint(car))
      asc[pos] = car;
    else
      asc[pos] = ' ';

    if(pos == 5)
      printf("%s\n", asc)
   
    offset++;
  }

  if(pos < 5)
  {   
    while(pos < 5)
    {
      printf("          ");
      asc[pos] = 0;
      pos++;
    }
    printf("%s\n", asc);
  }
 
  fclose(f);
  return 0;
}
 


C:\>bin bin.c
00 00101111 00101111 00100000 01100010 01101001 01101110 // bin
06 00101110 01100011 00001101 00001010 00100011 01101001 .c  #i
12 01101110 01100011 01101100 01110101 01100100 01100101 nclude
18 00100000 00111100 01110011 01110100 01100100 01101001  <stdi
24 01101111 00101110 01101000 00111110 00001101 00001010 o.h>
30 00100011 01101001 01101110 01100011 01101100 01110101 #inclu
36 01100100 01100101 00100000 00111100 01100011 01110100 de <ct
42 01111001 01110000 01100101 00101110 01101000 00111110 ype.h>
48 00001101 00001010 00001101 00001010 01101001 01101110     in
54 01110100 00100000 01101101 01100001 01101001 01101110 t main
60 00101000 01101001 01101110 01110100 00100000 01100001 (int a
66 01110010 01100111 01100011 00101100 00100000 01100011 rgc, c
72 01101000 01100001 01110010 00100000 00101010 00101010 har **
78 01100001 01110010 01100111 01110110 00101001 00001101 argv)
84 00001010 01111011 00001101 00001010 00100000 00100000  {
90 01000110 01001001 01001100 01000101 00100000 00101010 FILE *
96 01100110 00111011 00001101 00001010 00100000 00100000 f;
etc...


Pour diriger la sortie vers un fichier txt:

C:\>bin bin.c >bin.txt

C:\>


  • Partager sur Facebook
  • Partager sur Twitter
28 juillet 2007 à 17:53:10

Merci pour ce code :)
J'ai réussi à faire un petit compresseur, et pour le fichier sur lequel j'ai essayé le taux de compressage était de 44% environ, ce qui n'est pas mal pour ce que je veux faire :)

Vous pouvez le télécharger ici: http://www.yourcreations.fr/programmes.php?cat=Divers&id=29
  • Partager sur Facebook
  • Partager sur Twitter