2017-01-15 61 views
1

我試圖一次訪問二進制數據10位。我認爲最好的方法是在unsigned long long中讀入40位,然後使用位掩碼來訪問所需的數據。我的努力似乎讀了64位,我想知道是否有人能指出我要出錯的地方。謝謝。一次讀取二進制數據40位

FILE * pFile; 
long lSize; 
unsigned long long * buffer; 
size_t result; 

pFile = fopen ("test.bin" , "rb"); 
if (pFile==NULL) {fputs ("File error",stderr); exit (1);} 

fseek (pFile , 0 , SEEK_END); 
lSize = (ftell (pFile))/5; 
rewind (pFile); 

buffer = (unsigned long long*) malloc (sizeof(unsigned long long)*lSize); 
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);} 

result = fread (buffer,5,lSize,pFile); 
if (result != lSize) {fputs ("Reading error",stderr); exit (3);} 

當我輸出緩衝區[0]我越來越:

0100110111001110101110001110000111011111110001100011100110111011 

但我想我會得到這樣的:

0000000000000000000000001110000111011111110001100011100110111011 
+1

什麼是文件的TEST.bin,燒寫的實際內容是什麼?在一些十六進制編輯器中打開它,如HxD(假設你在Windows中工作)。 – Dialecticus

+2

用零初始化緩衝區 - 例如使用'calloc'。 – pSoLT

+0

@Dialecticus我剛剛下載了一個十六進制編輯器,並檢查了內容不匹配。有1011101100111001110001101101111100111001110001101101111111100001 – Kahless

回答

2

目前大多數操作系統不允許位訪問文件。文件通過系統調用(read() ...)或標準庫函數(getc(),fread() ...)逐字節讀取。

爲了將內容作爲位進行操作,您需要知道如何將這些位存儲(打包)到文件字節中。

有時比特首先打包到低位比特中,有時首先輸入高位比特,有時這種打包按字基準完成,這增加了額外的複雜度,因爲字可以以最低有效字節先存儲(又名小端格式)或最重要的字節(又名大端格式)。

一種常見的方法是保持一個字節的緩衝區與未讀位的計數一起:

typedef struct bitreader { 
    FILE *stream; 
    int bits; 
    unsigned char buffer; 
} bitreader; 

bitreader *bitopen(const char *filename) { 
    bitreader *bp = calloc(sizeof(*bp)); 
    if (bp) { 
     bp->stream = fopen(filename, "rb"); // open in binary mode 
     if (bp->stream == NULL) { 
      free(bp); 
      bp = NULL; 
     } 
    } 
    return bp; 
} 

void bitclose(bitreader *bp) { 
    fclose(bp->stream); 
    free(bp); 
} 

/* simplistic method to read bits packed with most significant bit first */ 
long long int bitread(bitreader *bp, int count) { 
    long long int val = 0; 
    while (count > 0) { 
     if (bp->bits == 0) { 
      int c = getc(bp->stream); 
      if (c == EOF) 
       return EOF; 
      bp->buffer = c; 
      bp->bits = 8; 
     } 
     val <<= 1; 
     val |= (bp->buffer >> 7) & 1; 
     bp->buffer <<= 1; 
     bp->bits--; 
     count--; 
    } 
    return val; 
} 
+0

謝謝你的回答,它非常全面。 – Kahless