6

我有一个将作为字符读入的二进制文件。每个字符都被其他人向左移动了未知次数(假设使用换行)。我希望能够读取每个字符,然后将 shift 向右换行(我猜要移动的次数必须手动计算,因为我还没有想出另一种方法)。

所以,我目前的想法是我读入一个字符,用 temp 创建一个副本,然后使用 XOR:

char letter;    //will hold the read in letter
char temp;      //will hold a copy of the letter
while(file.read(&letter, sizeof(letter)) //letter now holds 00001101
{
    temp = letter;  //temp now holds 00001101
    letter >>= 1;   //shift 1 position to the right, letter now holds 00000110
    temp <<= 7;     //shift to the left by (8-1), which is 7, temp now holds 10000000
    letter ^= temp; //use XOR to get the wrap, letter now holds 10000110
    cout << letter;
}

这在我疲惫的头脑中是有道理的,但它不起作用......我不知道为什么。char 的大小是 1 个字节,所以我想我只需要处理 8 位。

任何帮助,将不胜感激。

编辑:解决。非常感谢大家。爱死这个社区,你们太棒了!

4

3 回答 3

15

注意字符的符号。在许多系统上,它是签名的。所以你letter >>= 1的标志是填补班次。

旋转整数通常如下进行

letter = ((unsigned char)letter >> 1) | (letter << 7);

正如马克在评论中指出的那样,您可以使用 OR|或 XOR ^

于 2013-03-26T21:57:11.197 回答
0

该语句temp <<= 7正在丢失您要包装的位。您将需要一次循环左移一位。首先检查最重要的字符位,如果设置,在进行移位之前将其移动到最右边的位。

于 2013-03-26T22:02:20.667 回答
0

我倾向于使用更大的整数类型:

unsigned val = (unsigned)letter & 0xFF;
val |= val << 8;

现在您只需将值移入val,而无需任何额外的代码将高位包装回。

于 2013-03-26T22:13:27.807 回答