2014-02-18 45 views
1

通常位操作是以較小的數據寬度完成的,如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

拆分操作成字節和逐位的基礎上,採取由8 –

+0

您可以顯示一些分移大小的結果/餘代碼來說明你的建議(特別是我們如何確保鑽頭繼續存在)?例子會非常清楚。 – Babbit

+1

你正在通過調用'malloc'來泄漏內存,然後將一個字符串文字賦值給'record',並丟失分配內存上的句柄。簡單地做'char record [] =「NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S」;' – ajay

回答

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

} 
+0

完美貼子,@Jerry_Y! – Babbit

1

你的比特流本質上是char類型的數組。因此,要執行這些操作,您需要處理這些char元素。

我。移位操作取決於您想要移位的位數。 如果數字是8的倍數,則非常簡單,只需將左邊的元素複製爲數字爲8的倍數的字節即可。 如果數字小於8,則對每個元素執行操作數組的元素,但您需要或上一個元素的溢出位。例如,在左移中,元素i必須合併元素i + 1的溢出位,並且在右移時元素i-1的溢出位。 您想要移位的任何其他位數都可以通過這兩個操作的組合來實現。例如,左移18是移位16,然後移位2. 無論如何,您需要小心位置字符串的哪一邊,以免丟失數據。

ii。爲了獲得比特流的第n位,可以訪問索引爲n/8(整數除法)的元素,並從中得到n%8位。

iii。與ii非常相似。

+0

你能提供代碼片段來說明你的觀點嗎?我更關心一點點結轉。 – Babbit

相關問題