请问C语言里面有没有按bit位来处理文件的函数?
现在有一个结构体
struct RECT
{
unsigned int Nbits;//用5 bits 来表示其值。
signed int Xmin;//signed bit[Nbits]
signed int Ymin;
signed int Xmax;
signed int Ymax;
};
eg:对于文件内容:二进制形式:0111 1000 0000 0000 0000 0101 0101 1111 0000 0000
0000 0000 0000 1111 1010 0000 0000 0000
前面5个bits01111=15,所以下面4个变量都是用15个bits来存储,对应Xmax=010101011111000=11000(十进制)当然,在文件的其它位置可能计算出来的Nbits=16,或者其它的值。
我想编一个函数,根据文件的内容计算出相应的Xmin,Ymin...由于Nbits是变化的,所以需要按bit为单位来读,不知道c语言里面有没有这样的函数,或者有没有另外的方法解决这个问题。
谢过先!
问题点数:20、回复次数:22Top
1 楼milozy1983(Detective)回复于 2004-12-01 19:29:37 得分 3
应该只可以自己读出来后位操作吧Top
2 楼xzxsimon(歪歪)回复于 2004-12-01 19:34:56 得分 0
问题是由于Nbits可以是15,也可能是3,这样就使得nbits=15的时候,一个Xmax要跨越2~3个bytes
当nbits=3的时候,只要读一个bytes就可以将Xmax包含在里面了。Top
3 楼milozy1983(Detective)回复于 2004-12-01 19:54:44 得分 0
可能具体得意思我还没清楚,但如果是空间上需要节约得话,可以把标志位和结构体分开来存储,这样做存储和读得时候麻烦点Top
4 楼xzxsimon(歪歪)回复于 2004-12-01 20:03:40 得分 0
就是为了节约才会出现这样的结构的。
Top
5 楼milozy1983(Detective)回复于 2004-12-01 20:08:09 得分 0
如果先读一个字节的标志位然后判断读多少字节的结构体就没这个问题了,而且是节约的。Top
6 楼xzxsimon(歪歪)回复于 2004-12-01 20:21:06 得分 0
呵呵,我是想编一种文件格式的解码器。它的文件格式本身就是这样的,为了节约空间,使用了一个Bit Value的结构,就是能只用1个bit表示的就只用1个bit来表示。
c语言里面的好像都是按byte来读的,我不知道该怎么办了。
对于struct abc
{
unsigned int a1;
unsigned int a2;
unsigned int a3;
unsigned int a4;
unsigned int a5;
unsigned int a6;
unsigned int a7;
unsigned int a8;
};
这样的结构体,它都是存储在一个byte里面,我可以先把整个byte读出来,再用位操作来计算出每个分量的值,但是对于上面的RECT结构,它的变量所对应的存储位置和大小是根据Nbits的大小来变化的,这种方法就失效了Top
7 楼xzxsimon(歪歪)回复于 2004-12-01 20:21:58 得分 0
对了,abc结构体中的每个变量在文件中都只是用1个bit的空间来存储的。Top
8 楼milozy1983(Detective)回复于 2004-12-01 20:27:53 得分 0
如果abc结构中的8个变量都只是1个位的话最节约的就是干脆用一个字节来存放这8位算了,只是进行I/O操作的时候麻烦点,但一个字节存放8位正好。Top
9 楼xzxsimon(歪歪)回复于 2004-12-01 20:41:35 得分 0
文件里面就是只用了1个字节来存这8位。这种情况是我已经知道了这个字节在哪里,我可以把它读出来;而且也知道了abc.a1对应的是这个字节的最高位,abc.a2对应这个字节的第二位,等等。我知道了具体的位置,我就可以求出分量的值。
但是对于RECT的结构我不知道每个分量所在字节中的具体位置,不好求值。
所以我想问问有没有按bit来读的函数,这样我可以用一个for(i=0;i<nbits;i++){ read(bit);}来计算Xmax,Ymax等等。Top
10 楼milozy1983(Detective)回复于 2004-12-01 20:45:37 得分 0
应该没按位读的函数吧,具体的你可以去查下函数大全Top
11 楼xzxsimon(歪歪)回复于 2004-12-01 20:52:11 得分 0
没有查到。郁闷的很Top
12 楼archim(PRC)回复于 2004-12-01 21:53:39 得分 1
答案是没有Top
13 楼mathe()回复于 2004-12-02 10:03:08 得分 11
自己来写个函数呀:
static int bitleft=0;
static unsigned char prev_byte;
int GetShortBits(int bits)//bits must be no more than 8
{
int result;
int value=prev_byte;
if(bits>bitleft){
unsigned char new_byte=GetNextByteFromTheFile();//Implement the function yourself
value+=new_byte<<8;
bitleft+=8;
prev_byte=new_byte;
}
result=(value>>(8-bitleft))&((1<<bits)-1);
bitleft-=bits;
return result;
}
int GetBits(int bits) //Could get up to 32 bits
{
if(bits<=8)return GetShortBits(bits);
if(bits<=16)return (GetShortBits(bits-8)<<8)+GetShortBits(8);
if(bits<=24)return (GetShortBits(bits-16)<<16)+(GetShortBits(8)<<8)+GetShortBits(8);
if(bits<=32)return (GetShortBits(bits-24)<<24)+(GetShortBits(8)<<16)+(GetShortBits(8)<<8)+GetShortBits(8);
ASSERT(0);
return -1;
}
void GetNextRect(struct RECT *rect)
{
rect->Nbits=GetBits(5);
rect->Xmin=GetBits(rect->Nbits);
rect->XMax=GetBits(rect->Nbits);
rect->YMin=GetBits(rect->Nbits);
rect->YMax=GetBits(rect->Nbits);
}Top
14 楼xzxsimon(歪歪)回复于 2004-12-02 10:33:47 得分 0
不太明白GetShortBits(int bits)这个函数的意思。
在这个函数里面:
1。prev_byte指的是哪个?比方说文件内容是二进制形式:0111 1000 0000 0000,那么prev_byte指的是01111000?
2。bitleft起什么作用的?
当我求RECT->Nbits的时候,利用GetShortBits(5)来求,bits==5,这个时候if语句成立,并且执行一次后bitleft变成8,不再满足if的条件,所以继续执行下面的result=(value>>(8-bitleft))&((1<<bits)-1);在这个语句里面8-bitleft不就等于0么?那value>>(8-bitleft)就没有意义了。Top
15 楼pcboyxhy(-273.15℃)回复于 2004-12-02 12:10:55 得分 1
没有,
文件的最小单位就是字节Top
16 楼xzxsimon(歪歪)回复于 2004-12-02 20:03:07 得分 0
谢谢mathe,谢谢各位。
mathe,你的思路很棒,我总算想明白了。不过程序段有点问题,
1。getshortbits()里面的if语句内的value值计算 应该是value=(value<<8)+new_byte;
2。getshortbits()里面的 应该是result=(value>>(bitleft-bits))&((1<<bits)-1);Top
17 楼mathe()回复于 2004-12-03 16:11:49 得分 0
rightTop
18 楼nohymn(小强)回复于 2004-12-03 19:25:36 得分 1
可是 我不是很明白 难道 那样一声明就是按位存储了吗
struct abc
{
unsigned int a1;
unsigned int a2;
unsigned int a3;
unsigned int a4;
unsigned int a5;
unsigned int a6;
unsigned int a7;
unsigned int a8;
};
这样就可以了吗我实在不知道 原来这样就可以
真是谢谢啦Top
19 楼spider_xm(桃花老怪)回复于 2004-12-03 20:11:28 得分 1
可以这样定义结构吗,那结构的长度不是定长咯,如果sizeof不知是什么结果?Top
20 楼idler(告别teenage)(偶是豆子。。。)(歇业休息。。。)回复于 2004-12-03 20:13:31 得分 1
没有按位操作文件的机制Top
21 楼klnight(will)回复于 2004-12-03 20:28:25 得分 0
我也来写种方法也许对你有帮助。
union getBitUnion{
}Top
22 楼klnight(will)回复于 2004-12-03 20:30:43 得分 1
不好意思,按错了
union getBitUnion{
struct everyBit{
BYTE b0:1;
BYTE b1:1;
..
BYTE b7:1;
}8bits
BYTE wholeByte;
}Top




