2015-09-05 82 views
0

假设我有一个字符数组,并且我想将N位左移每个字节左边,所以只有第一个字符的N位会丢失。移位N位整个字符数组

举例:kxmo移3位向左应该成为[email protected]

这是我现在,但它不是按预期工作:

#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]; //[email protected] 

    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 | new: �xmo

+0

什么问题?你在调试器中得到什么?你有什么自己尝试过的? – Olaf

+0

@Olaf我得到' xmo',这不是我所期待的。我已经尝试了我在我的问题中编写的代码。 – alexandernst

+1

'0 |无论与“无论”都一样。你是如何计算样本结果的?你的代码是否一样?提示:XOR在这里没用。 – Olaf

回答

1

如何类似的东西(假设0 < = shift < 8):

#define BITS_IN_BYTE 8 
for(int i = len - 1; i > 0; i--) 
{ 
    b[i] = a[i] << shift; 
    b[i - 1] = (a[i - 1] << shift) | (a[i] >> (BITS_IN_BYTE - shift)); 
} 

我没有”检查它,但我希望它会做你想做的。

编辑

OK,我检查,它确实你所期望的。

注意 - >您需要将len设置为5,而不是'\0'。还要注意,第一次迭代(b[i] = a[i] << shift;)将在'\0'上完成,但由于它的值为0,所以可以。

+0

刚刚尝试过,输出的第二个字符不是'@',这意味着它没有按预期工作。 – alexandernst

+0

@alexandernst :)它不能是3个字符匹配,只有一个不匹配。预测中有一个错误。 'x'的值是0x78,如果你将它左移3,你得到的0xC0不是'@',它的ASCII代码是0x40。请再检查一次。 –

+0

@dasblinkenlight当然你是对的。我的错。已经修复它。谢谢。 –

1

首先,想象用铅笔和纸做的。假设您正在将两个字节移位三位,您从字节abcdefgh,ijklmnop开始,并且您想以defghijklmnop000结束。

为了做到这一点,您需要从第二个字节中提取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; 

如果你这样做在一个循环中,你会达到预期的效果。

Demo.

+0

非常好的解释!让我试试看。 – alexandernst

+0

我正在测试你的代码,但输出不是我所期望的。这是'printf(“%s”,b);' - >'[ kx'的输出。最后一个字符是好的,但从那里开始,所有其他字符都是错误的。 – alexandernst

+0

@alexandernst您期待的结果不正确。如果您手动将'{6B 78 6D 6F}'的''kxmo''左移三位,则会得到'{5B C3 6B 78}',即'[ kx''。 – dasblinkenlight