如何在char字符串中获取和设置位的位数?

时间:2014-02-18 17:05:25

标签: c string bit

通常位操作以较小的数据宽度完成,例如int,unsigned int或wchar_t。假设我们想要以更长的格式使用位串,如何在char字符串中移位,获取和设置位的位?

一种方法可能是使用传统方法进行分割和征服,但我们如何确保比特结转?

给出

#define numberOfState 2000  // number of bits
#define numberOfBitsIn1Byte 8

char* record;

int numberOfCharRequiredToRepresentBits = 
                     ceil(((float)numberOfState/(float)numberOfBitsIn1Byte));


record = (char*) malloc(sizeof(char)*numberOfCharRequiredToRepresentBits);
// record = "NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S"; 
// optional : initialization by doing the set bit according to 
//            input from files. After which, do free(record);

我们如何进行比特操作,例如

i. shift the *record
ii. get bits from a specific bit position in *record
iii. set bits from a specific bit position in *record

2 个答案:

答案 0 :(得分:1)

您的比特流本质上是一个char数组。因此,要执行这些操作,您需要处理这些char元素。

我。移位操作取决于您想要移位的位数。 如果数字是8的倍数,则非常简单,只需将左边的元素复制为字节数,因为数字是8的倍数。 如果数字小于8,则对数组的每个元素执行操作,但是您需要或前一个元素的溢出位。例如,在左移,元素i必须包含元素i + 1的溢出位,并且在右移,元素i-1的溢出位。 您想要移位的任何其他位数都可以通过这两个操作的组合来实现。例如,左移18,是16的移位,然后是2的移位。 在任何情况下,您都需要注意开始位串的哪一侧,这样就不会丢失数据。

II。为了获得比特流的第n位,可以访问索引为n / 8(整数除法)的元素,并从中获取n%8位。

III。与ii。几乎相同。

答案 1 :(得分:1)

请尝试使用以下代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int isLittleEndian = 1;

void checkEndian(void)
{
    union  
    {  
        short   inum;  
        char c[sizeof(short)];  
    } un;  

    un.inum=0x0102;  

    if(un.c[0]==1 && un.c[1]==2) 
    {
        printf("big_endian.\n"); 
        isLittleEndian = 0;
    }
    else if(un.c[0]==2 && un.c[1]==1)
    {
        printf("little_endian.\n"); 

        isLittleEndian = 1;
    }

}

void shift_L(char *src, char * dst, int len, int n)
{
    int shiftBytes = n/8;
    int shiftBits = n%8;

    memset(dst, 0, len);
    memcpy(dst, src + shiftBytes, len - shiftBytes);

    if (shiftBits)
    {
        int i = 0;
        unsigned short tmp = 0;

        for ( i = 0; i < len; i++)
        {
            if (isLittleEndian)
            {
                tmp = *(dst+i) << 8 | *(dst+i+1);
                tmp <<= shiftBits;
                *(dst+i) = *((char *)&tmp + 1);
            }
            else
            {
                tmp = *(short *)(dst+i);
                tmp <<= shiftBits;
                *(dst+i) = *((char *)&tmp);
            }
        }
    }
}

void shift_R(char *src, char * dst, int len, int n)
{
    int shiftBytes = n/8;
    int shiftBits = n%8;

    memset(dst, 0, len);
    memcpy(dst + shiftBytes, src, len - shiftBytes);

    if (shiftBits)
    {
        int i = 0;
        unsigned short tmp = 0;

        for ( i = len -1; i >= 0; i--)
        {
            if (isLittleEndian)
            {
                tmp = *(dst+i-1) << 8 | *(dst+i);
                tmp >>= shiftBits;
                *(dst+i) = *((char *)&tmp);
            }
            else
            {
                tmp = *(short *)(dst+i-1);
                tmp >>= shiftBits;
                *(dst+i) = *((char *)&tmp+1);
            }
        }
    }
}

int getBit(char *src, int n)
{
    unsigned char tmp = *(src + n/8);
    unsigned char mask = (0x1 << (8 - n%8 - 1));
    int bit = 0;

    bit =  (tmp & mask) > 0;
    printf("%d", bit);
}

void setBit(char *src, int n, int bit)
{
    unsigned char * pTmp = src + n/8;
    unsigned char mask = (0x1 << (8 - n%8 - 1));

    if (bit)
    {
        *pTmp |= mask;
    }
    else
    {
        *pTmp &= ~mask;
    }
}

void dumpBin(unsigned char *src, int len)
{
    int i = 0;
    int j = 0;
    unsigned char mask = 0;

    for ( i = 0; i < len; i++)
    {
        for ( j = 0; j < 8; j++)
        {
            mask = 0x1 << 8 - j - 1;
            printf("%d",(*(src + i) & mask) > 0); 
        }    
    }
}

void main()
{
    char *record = "NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S";
    //char *record = "NAXHDKA";

    int recordLen = strlen(record);
    char * buffer = NULL;
    int i = 0;

    checkEndian();

    recordLen = recordLen + recordLen%2;
    buffer = malloc(recordLen);
    memcpy(buffer, record, recordLen);

    printf("\n input bit stream:\n");
    dumpBin(buffer, recordLen);


    printf("\n bit stream from getBit:\n");
    for ( i = 0; i < recordLen*8; i++)
    {
        getBit(buffer, i);
    }


    setBit(buffer, 8, 1);
    setBit(buffer, 9, 0);
    setBit(buffer, 10, 1);
    setBit(buffer, 11, 1);
    printf("\n bit stream after setBit:\n");
    dumpBin(buffer, recordLen);


    shift_L(record, buffer, recordLen, 1);
    printf("\n bit stream after shift_L:\n");
    dumpBin(buffer, recordLen);


    shift_R(record, buffer, recordLen, 9);
    printf("\n bit stream after shift_R:\n");
    dumpBin(buffer, recordLen);

    printf("\n");

    free(buffer);

}