在C中读取固定数量的字节?

时间:2012-09-17 23:31:37

标签: c

我必须编写一个可以一次读取三个字节数据的算法,如下所示:

例如,假设用户输入:Uof

二进制中的Uof将显示为01010101 01101111 01100110

我需要帮助将其分成四个相等的部分,每个部分分别为六位:

010101(21)

010110(22)

111101(61)

100110(38)

我只允许使用整数。 我可以读取第一个字符,将它向右移动两个并获得结果21没问题。

获得22对我没有意义。任何指针都会有所帮助,不需要确切的解决方案,但是什么能让我思考?

2 个答案:

答案 0 :(得分:1)

问问自己:

  • 每个部分的6位来自哪里?

  • 如何将位移动到值中的其他位置?

  • 如何组合两个值,以便只拍摄每个值的有趣位?

为了帮助您回答第三个问题,您可能也会问自己:

  • 我如何掩盖一个值,以便有趣的位保持原样,非感兴趣的位全部变为0(或全部变为1)?

答案 1 :(得分:0)

好的,首先,我们将尝试将3个字节放入一个整数。我们将使用shift和OR逻辑。假设我们有abc个输入变量。 (Uof会分别分为abc

我们首先为b变量添加1个字节的空格:

(b << 8)

因此01101111转换为0110111100000000

现在我们OR c进入b,所以零实际上是c

((b << 8) | c))

现在,我们对a执行相同的逻辑。我们在a的右侧保留了更多16位,因此我们可以OR我们获得的最后一个表达式。

((a << 16) | ((b << 8) | c))

到目前为止,我们将所有位合并为一个4字节整数。

我们现在只需要将它分成4个部分,每部分6位。我们将使用掩码逻辑。

首先,当我们使用“掩码”逻辑时,我们必须自己制作掩码。我们的掩码是0x3F(来自二进制数111111,即6位),所以当我们AND数字时,使用这个掩码,我们可以提取右侧的前6位:

r1 = (merged & 0x00003F);

r1代表result 1

现在,同样的事情,但是右边的合并数字为6位,所以我们可以采用下一个6位数字,依此类推,其余部分:

r1 = ((merged >> 0)  & 0x3F);
r2 = ((merged >> 6)  & 0x3F);
r3 = ((merged >> 12) & 0x3F);
r4 = ((merged >> 18) & 0x3F);

所以,最终的代码是:

char /*or int*/ a, b, c;
int merged, r1, r2, r3, r4;

scanf(" %c %c %c", &a, &b, &c);

merged = ((a << 16) | ((b << 8) | c));

r1 = ((merged >> 0)  & 0x3F);
r2 = ((merged >> 6)  & 0x3F);
r3 = ((merged >> 12) & 0x3F);
r4 = ((merged >> 18) & 0x3F);

printf("%d %d %d %d\n", r1, r2, r3, r4);

编辑:我更正了面具部分。