假设我有一个字符数组,我想将每个字节向左移动 N 位,向左移动,因此只有第一个字符的 N 位会丢失。
示例:kxmo
向左移动 3 位应成为 X@hx
这是我目前拥有的,但它没有按预期工作:
#include <stdio.h>
int main(void) {
//shift the array with length *len* *shift* bits to the left
int len = 4, shift = 3;
unsigned char a[len] = "kxmo";
unsigned char b[len]; //X@hx
unsigned char tmp = 0, tmp2 = 0;
for(int i = len - 1; i > 0; i--) {
tmp = 0 | (a[i] << shift);
b[i] = a[i];
tmp2 = 0 | (a[i - 1] << shift);
b[i - 1] = (a[i - 1] << shift) ^ tmp;
}
printf("old: %s | new: %s\n", a, b);
return 0;
}
我哪里失败了?
编辑:
这就是我现在得到的:old: kxmo |新:�xmo
最佳答案
首先,想象一下用铅笔和纸来做这件事。假设您要将两个字节移动三位,您以字节 abcdefgh
、ijklmnop
开始,并希望以 defghijk
、lmnop000
.
为此,您需要从第二个字节中提取00000ijk
,并在移位后将其OR
到第一个字节中。为此,您需要将第二个字节8-shift
移到右边,并用00000111
屏蔽结果,即最后一个 shift
位设置为 1
。这个掩码可以通过将 1
向左移动 shift+1
次,产生 00001000
,然后减去 1
来构造从结果来看。
这里是你如何做到的:
char b1 = 'k';
char b2 = 'x';
int shift = 3;
int carry = 0, nextCarry;
nextCarry = (b1 >> (8-shift)) & ((1<<(shift+1))-1);
b1 <<= shift;
b1 |= carry;
carry = nextCarry;
现在对 b2
做同样的事情:
nextCarry = (b2 >> (8-shift)) & ((1<<(shift+1))-1);
b2 <<= shift;
b2 |= carry;
carry = nextCarry;
如果您在循环中执行此操作,您将获得所需的结果。
关于c - 将整个字符数组移位 N 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32412281/