将一个字符数组视为比特流的C/C++代码

8

我有一个char[]数组中的大块二进制数据,我需要将其解释为一组紧密打包的6位值。

我可以写一些代码来完成这个任务,但我认为肯定已经有人写过一个好的类或函数了。

我需要的是像这样的东西:

int get_bits(char* data, unsigned bitOffset, unsigned numBits);

通过调用以下方法,我可以获取数据中的第7个6位字符:

const unsigned BITSIZE = 6;
char ch = static_cast<char>(get_bits(data, 7 * BITSIZE, BITSIZE));

可能对你来说编写代码更快。 - mdec
这不会是FIELDATA吧?http://www.fourmilab.ch/documents/univac/fieldata.html - warren
不,实际上是路透社MarketFeed。 - AndrewR
3个回答

7

是的,我考虑过那个,但我希望有一种方法可以在取出位时将它们重新打包成一个int。 - AndrewR

5

这种方法在大小超过8的情况下可能无法正常工作,取决于字节顺序。基本上就是Marco发的那个代码,不过我不太确定他为什么要逐位收集。

int get_bits(char* data, unsigned int bitOffset, unsigned int numBits) {
    numBits = pow(2,numBits) - 1; //this will only work up to 32 bits, of course
    data += bitOffset/8;
    bitOffset %= 8;
    return (*((int*)data) >> bitOffset) & numBits;  //little endian
    //return (flip(data[0]) >> bitOffset) & numBits; //big endian
}

//flips from big to little or vice versa
int flip(int x) {
    char temp, *t = (char*)&x;
    temp = t[0];
    t[0] = t[3];
    t[3] = temp;
    temp = t[1];
    t[1] = t[2];
    t[2] = temp;
    return x;
}

超过32位的技巧是什么(例如“long long”)?将值存储在char数组中的代码可能是什么样子? - Will

1

我认为以下类似的代码可能会起作用。

int get_bit(char *data, unsigned bitoffset) // returns the n-th bit
{
    int c = (int)(data[bitoffset >> 3]); // X>>3 is X/8
    int bitmask = 1 << (bitoffset & 7);  // X&7 is X%8
    return ((c & bitmask)!=0) ? 1 : 0;
}

int get_bits(char* data, unsigned bitOffset, unsigned numBits)
{
    int bits = 0;
    for (int currentbit = bitOffset; currentbit < bitOffset + numBits; currentbit++)
    {
        bits = bits << 1;
        bits = bits | get_bit(data, currentbit);
    }
    return bits;
}

我还没有调试或测试它,但你可以把它作为一个起点。

另外,请考虑位序。你可能需要进行更改。

    int bitmask = 1 << (bitoffset & 7);  // X&7 is X%8

    int bitmask = 1 << (7 - (bitoffset & 7));  // X&7 is X%8

根据位数组的生成方式而定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接