我正在使用C来实现将通过无线发送的数据包流,并且遇到以下问题。我有一个2字节长的unsigned int,在二进制文件中采用以下格式: XXXX YYYY XXXX XXXX,其中X& Y是比特。
查看上面的格式,我需要更改YYYY位并将其他位保留在数据包结构中。
我尝试过移位和屏蔽,但似乎没有任何效果。
我不是在寻找一个解决方案,所以我可以复制/粘贴。我想学习如何让它工作的方法,最后决定在这里发布。
任何正确方向的帮助或指导都会很棒。
谢谢!
答案 0 :(得分:6)
假设您想用ZZZZ替换YYYY位。
首先,您需要清除原始值中的YYYY位。这可以通过以下方式完成:
oldvalue & 0xF0FF
为您提供XXXX 0000 XXXX XXXX
。
接下来,您需要使用新的ZZZZ位并将它们移到左侧,使用:
z << 8
给出了0000 ZZZZ 0000 0000
。
最后,您需要使用或运算符组合这两个值:
(oldvalue & 0xF0FF) | (z << 8)
为您提供XXXX ZZZZ XXXX XXXX
。
答案 1 :(得分:0)
value = (value & 0xF0FF) | (newY << 8);
或其近似变体,取决于字节顺序?
答案 2 :(得分:0)
您对问题的描述可能与某些代码有关,但我认为您可能遇到了一个字节序问题。这可以解释为什么你的移位和掩蔽没有按照你的想法去做,因为你实际上在处理错误的字节。
hton和ntoh函数系列切换到主机和网络端(大端)。查看htons,ntohs,htonl和ntohl以获取更多信息。如果主机是大端,这些功能实际上并没有做任何事情,但许多(如x86)计算机都是小端。在一个小端计算机上,htons(0x1234)会导致0x3412,因为它会交换字节。
因为我不知道你的程序流程是什么样的,所以我最好尝试一个明确的例子。
uint16_t set_those_bits(uint16_t x) {
uint16_t mask = htons(0x0F00);
return x | mask;
}
此函数不会改变相对于返回值传入的数据的字节序,但它确实假定该值为network endian,因此将掩码的endian-ness从host endian更改为network在结果中设置这些位。
uint16_t clear_those_bits(uint16_t x) {
uint16_t mask = htons(0xF0FF);
return x & mask;
}
uint16_t toggle_those_bits(uint16_t x) {
uint16_t mask = htons(0x0f00);
return x ^ mask;
}