繁体   English   中英

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

[英]How to get and set bits for bits in char string?

通常,位操作以较小的数据宽度完成,例如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

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

一世。 移位操作取决于您要移位的位数。 如果数字是8的倍数,这很简单,您只需将元素复制到左侧,就跟数字是8的倍数一样多。如果数字小于8,则对元素的每个元素执行操作。数组,但是您需要或上一个元素的溢出位。 例如,在左移时,元素i必须合并元素i + 1的溢出位,而在右移时,元素i-1的溢出位必须合并。 这两个动作的组合可以实现您要移位的其他位数。 例如,左移18即是移16再乘以2。在任何情况下,都需要注意从位串的哪一侧开始,以免丢失数据。

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

III。 与ii几乎相同。

请尝试以下代码:

#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);

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM