Datei bitweise lesen



  • Hallo allerseits,

    ich möchte eine Datei bitweise lesen, leider weiß ich nicht wie.
    Es geht darum, header auszulesen. Also angenommen ich bräuchte die
    ersten 7 Bit einer Datei...
    Mit fread fällt mir nichts vernünftiges ein, da ich halt keinen
    geeigneten Datentyp habe. Ich brauche keine Komplettlösung. Ich wäre
    schon für Hinweise dankbar.

    Danke und Gruß

    Roby



  • ich würde einfach fopen verwenden und einfach mal alle in char einlesen und mit Bitoperationen, dann die einzelnen informationen aus den Bits ziehen



  • Also einlesen musst du mindestens ein Byte. Kleinere Einheiten geht nicht, da das auch die Auflösung des Filepointers ist.

    Wie du ein Byte in Bits aufsplittest, musst du mal hier und im C++ Forum suchen, da gibt es schon einige Beiträge.



  • zum Thema Bitoperationen:
    http://courses.iicm.edu/the_c_book/SoftwareentwicklungInC.pdf
    siehe Kapitel 4



  • Du könntest ein paar byte(die größe des headers) in ein char-array einlesen und dann mit den bit-operatoren die gesetzten bzw. nicht gesetzten bits überprüfen.



  • Danke für Eure schnelle Hilfe.
    Ok, dann muss ich wohl erstmal alles Byteweise einlesen, in Char-Array konvertieren (zusammensetzen), splitten und in int konvertieren.
    Ich hatte gehofft, es geht bitweise auszulesen.
    Bleibt mir wohl die Arbeit nicht erspart 😉

    Euch vielen Dank!

    Gruß

    Roby



  • #include <stdbool.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <stdio.h>
    
    /* ggf. einkommentieren, falls kein "stdbool.h", und falls Compiler Fehlermeldung vor "bool" bringt:
    typedef enum _bool { false, true } bool;
    */
    
    typedef unsigned char byte_t;
    typedef unsigned char bit_t;
    
    typedef struct _bitreader_t {
       FILE*  fp;
       byte_t current_byte;
       byte_t byte_mask;
       bit_t  current_bit;
    } bitreader_t;
    
    void init_bitreader( bitreader_t* br, FILE* fp ) {
       br->fp = fp;
       br->current_byte = (byte_t) '\0';
       br->byte_mask    = (byte_t) '\0';
       br->current_bit  = 0;
    }
    
    bool readbyte( bitreader_t* br ) {
       int c = getc( br->fp );
       if ( c == EOF ) return false;
       br->current_byte = (byte_t) c;
       br->byte_mask    = (byte_t) ( 1 << ( CHAR_BIT - 1 ) );
       return true;
    }
    
    bool readbit( bitreader_t* br ) {
       if ( br->byte_mask == (byte_t) '\0' ) {
          if ( !readbyte( br ) ) return false;
       }
       br->current_bit = ( br->current_byte & br->byte_mask ) != 0 ? 1 : 0;
       br->byte_mask >>= (byte_t) '\x01';
       return true;
    }
    
    int main( int argc, char** argv ) {
       bitreader_t br; FILE* fp; int bi, wi, ba;
       if ( argc < 2 ) {
          fprintf( stderr, "usage: %s <filename>\n", argv[0] );
          return 0;
       }
       fp = fopen( argv[1], "rb" );
       if ( fp == 0 ) {
          fprintf( stderr, "file \"%s\" not found!\n", argv[1] );
          return 0;
       }
       init_bitreader( &br, fp );
       bi = 0;  /* bit index */
       wi = 0;  /* word index */
       ba = 0;  /* bit address */
       printf( "%-010.10d: ", ba );
       while ( readbit( &br ) ) {
          char c = br.current_bit ? '1' : '0';
          putchar( c ); ++ba;
          if ( ++bi == CHAR_BIT ) {
             bi = 0; putchar( ' ' );
             if ( ++wi == 4 ) {
                putchar( ' ' );
             }
             else if ( wi == 8 ) {
                putchar( '\n' );
                wi = 0;
                printf( "%-10.10d: ", ba );
             }
          }
       }
       putchar( '\n' );
       fflush( stdout );
       fclose( fp );
       return 0;
    }
    

    😃



  • oder einfach sowas:

    bool Read1Bit(FILE *fInput)
    {
    	static char buffer = 0;
    	static char	current = 8;
    
    	if (current >= 8)
    	{
    		buffer = getc(fInput);
    		current = 0;
    	}
    	return (buffer & (1 << (7-current++)));
    }
    


  • Herr-Vorragend schrieb:

    oder einfach sowas:

    bool Read1Bit(FILE *fInput)
    {
    	static char buffer = 0;
    	static char	current = 8;
    
    	if (current >= 8)
    	{
    		buffer = getc(fInput);
    		current = 0;
    	}
    	return (buffer & (1 << (7-current++)));
    }
    

    Das ist fuer den Anfang zwar ok, aber es gibt zwei potentielle Probleme:

    1. Es wird angenommen, dass "char" immer 8 Bit gross ist. Um das Problem zu loesen, muesste die Routine so aussehen:

    #include <limits.h>
    bool Read1Bit(FILE *fInput)
    {
    	static char buffer = 0;
    	static char	current = CHAR_BIT;
    
    	if (current >= CHAR_BIT)
    	{
    		buffer = getc(fInput);
    		current = 0;
    	}
    	return (buffer & (1 << (CHAR_BIT-1-current++)));
    }
    

    2. Durch die Verwendung von "static"-Variablen ist die Routine nicht multithreadfaehig. Das mag zwar jetzt kein Problem darstellen, aber man stelle sich tausende solcher Funktionen vor, die in einer Multithread-Anwendung verwendet werden sollen. Dann hat man auf einmal alle Haende voll zu tun.

    😉

    EDIT:
    3. Hier noch ein drittes Problem: EOF wird voellig ignoriert!


Anmelden zum Antworten