簡體   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