C 一次读取40位二进制数据

C 一次读取40位二进制数据,c,C,我试图一次访问10位二进制数据。我认为最好的方法是将40位读入无符号long,然后使用位屏蔽来访问所需的数据。我的努力似乎读到了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

我试图一次访问10位二进制数据。我认为最好的方法是将40位读入无符号long,然后使用位屏蔽来访问所需的数据。我的努力似乎读到了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

大多数当前操作系统不允许对文件进行位访问。通过系统调用(
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;
}
typedef结构位读取器{
文件*流;
整数位;
无符号字符缓冲区;
}比特阅读器;
bitreader*bitopen(常量字符*文件名){
比特读取器*bp=calloc(sizeof(*bp));
如果(bp){
bp->stream=fopen(文件名,“rb”);//以二进制模式打开
如果(bp->stream==NULL){
自由基(bp);
bp=NULL;
}
}
返回bp;
}
无效位关闭(位读取器*bp){
fclose(bp->stream);
自由基(bp);
}
/*先读取包含最高有效位的位的简化方法*/
长整型位读取(位读取器*bp,整型计数){
long int val=0;
而(计数>0){
如果(bp->位==0){
int c=getc(bp->stream);
如果(c==EOF)
返回EOF;
bp->buffer=c;
bp->bits=8;
}
val>7)和1;

bp->buffer文件test.bin的实际内容是什么?在一些十六进制编辑器中打开它,比如HxD(假设您在Windows中工作)。用零初始化缓冲区-例如使用
calloc
。@我刚下载了一个十六进制编辑器并进行了检查,但内容不匹配。当我输出缓冲区[0]时有10111011100111000110101011111111111110011100011010101111100001“…”似乎没有使用标准的C库函数。你是如何得到这个输出的?@RadLexus我用过cout。谢谢你的回答,非常彻底。