我试图一次访问10位二进制数据。我认为最好的方法是在无符号长long读取40位,然后使用位屏蔽来访问所需的数据。我的努力似乎读了64位,我想知道是否有人可以指出我出错的地方。感谢。
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
答案 0 :(得分: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;
}