简体   繁体   中英

How to get certain bits of a char array to another char array in C?

I have a char (input) array with size 60. I want to write a function that returns certain bits of the input array.

char  input_ar[60];

char output_ar[60];

void func(int bits_starting_number, int total_number_bits){

}

int main()
{

input_ar[0]=0b11110001; 

input_ar[1]=0b00110011; 

func(3,11);

//want output_ar[0]=0b11000100; //least significant 6 bits of input_ar[0] and most significant bits (7.8.) of input_ar[1]

//want output_ar[1]=0b00000110; //6.5.4. bits of input_ar[1] corresponds to 3 2 1. bits of  output_ar[1] (110)  right-aligned other bits are 0, namely 8 7 ...4 bits is zero


}

I want to ask what's the termiology of this algorithm? How can I easily write the code? Any clues appricated.

Note: I use XC8, arrray of bits are not allowed.

First of all, the returntype: You can return a boolean array of length total_number_bits.

Inside your function you can do a forloop, starting at bits_starting_number, iterating total_number_bits times. For each number you can divide the forloopindex by 8 (to get the right char) and than bitshift a 1 by the forloopindex modulo 8 to get the right bit. Put it on the right spot in the output array (forloopindex - bits_starting_number) and you are good to go

This would become something like:

for(i = bits_starting_number; i < bits_starting_number + total_number_bits; i++) {
    boolarr[i - bits_starting_number] = charray[i/8] & (1 << (i % 8));
}

This answer makes the following assumptions. Bits are numbered from 1, the first bit is the MS bit of the first byte. The extracted bit array must be left-aligned. Unused bits on the right are padded with 0.

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

#define MAX_LEN 60
#define BMASK   (1 << (CHAR_BIT-1))

unsigned char  input_ar[MAX_LEN];
unsigned char output_ar[MAX_LEN];

int func(int bits_starting_number, int total_number_bits) {
    // return the number of bits copied
    int sors_ind, sors_bit, dest_ind = 0;
    int i, imask, omask;
    memset (output_ar, 0, MAX_LEN);         // clear the result
    if (bits_starting_number < 1 || bits_starting_number > MAX_LEN * CHAR_BIT)
        return 0;                           // bit number is out of range
    if (total_number_bits < 1)
        return 0;                           // nothing to do
    bits_starting_number--;
    if (bits_starting_number + total_number_bits > MAX_LEN * CHAR_BIT)
        total_number_bits = MAX_LEN * CHAR_BIT - bits_starting_number;
    sors_ind = bits_starting_number / CHAR_BIT;
    sors_bit = CHAR_BIT - 1 - (bits_starting_number % CHAR_BIT);
    imask = 1 << sors_bit;
    omask = BMASK;
    for (i=0; i<total_number_bits; i++) {
        if (input_ar[sors_ind] & imask)
            output_ar[dest_ind] |= omask;   // copy a 1 bit
        if ((imask >>= 1) == 0) {           // shift the input mask
            imask = BMASK;
            sors_ind++;                     // next input byte
        }
        if ((omask >>= 1) == 0) {           // shift the output mask
            omask = BMASK;
            dest_ind++;                     // next output byte
        }
    }
    return total_number_bits;
}

void printb (int value) {
    int i;
    for (i=BMASK; i; i>>=1) {
        if (value & i)
            printf("1");
        else
            printf("0");
    }
    printf (" ");
}

int main(void) {
    int i;
    input_ar[0]= 0xF1;  // 0b11110001
    input_ar[1]= 0x33;  // 0b00110011 

    printf ("Input:  ");
    for (i=0; i<4; i++)
       printb(input_ar[i]);
    printf ("\n");

    func(3,11);

    printf ("Output: ");
    for (i=0; i<4; i++)
       printb(output_ar[i]);
    printf ("\n");
    return 0;
}

Program output

Input:  11110001 00110011 00000000 00000000
Output: 11000100 11000000 00000000 00000000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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