打包位并读取它们-C

问题描述 投票:2回答:2

以下是我要发送到服务器的声明:

typedef enum 
{
    GET = 0,
    SET = 1,
    UNDEF = 2,

} cmd_t;

struct  args 
{ 
    cmd_t cmd; 
    uint8_t value; 
    uint8_t id;
};

value的类型为uint8_t,例如,值为42id也是uint8_t,并且值为30cmd是我的typedef,例如GET也是0

我将此信息发送到像这样打包的服务器:

char buff[2];
buff[0] = arguments.cmd;
buff[0] += arguments.id << 2;

buff[1] = arguments.value;
send(sfd, buff, sizeof(buff), 0);

我在cmd的前2位的第一个字节中打包,然后将其移位2位并打包id。然后在第二个字节上打包value。我知道该值不能大于127,因此可以将其保留在字节的前7位。我也知道id不能超过63

Here is what I mean:

然后我在服务器上收到了。当我同时读取响应的第二个字节req[1]时,我会得到值42,但是当我同时读取我的第一个字节req[0]时,我又将其移位却无法获得030。 req被定义为req[2]。这是我尝试过的:

    for (size_t i = 0; i < 8; i++)
    {
       int idCMD = (uint8_t) (req[0]>>i);
       printf("idCMD -> %d\n", idCMD);
    }
    printf("\n");
     for (size_t i = 0; i < 8; i++)
    {
       int idCMD = (uint8_t) (req[0]<<i);
       printf("idCMD -> %d\n", idCMD);
    }

我如何读取我的cmd和ID?

输出:

    idCMD -> 121
    idCMD -> 60
    idCMD -> 30
    idCMD -> 15
    idCMD -> 7
    idCMD -> 3
    idCMD -> 1
    idCMD -> 0

    idCMD -> 121
    idCMD -> 242
    idCMD -> 228
    idCMD -> 200
    idCMD -> 144
    idCMD -> 32
    idCMD -> 64
    idCMD -> 128

我从中得到的是:

    printf("value -> %d\n", req[1]);
    printf("id -> %d\n", req[0] >> 2);
    printf("cmd-> %d\n", req[0] >> 6);

    value -> 42
    id -> 30
    cmd-> 1

我知道cmd也为1。如何确保我读到0而不是1?

但是似乎我没有正确阅读cmd。上面的输出是当cmd为1时。这是当cmd为0且值为0时:

idCMD -> 120
idCMD -> 60
idCMD -> 30
idCMD -> 15
idCMD -> 7
idCMD -> 3
idCMD -> 1
idCMD -> 0

idCMD -> 120
idCMD -> 240
idCMD -> 224
idCMD -> 192
idCMD -> 128
idCMD -> 0
idCMD -> 0
idCMD -> 0
value -> 0
id -> 30
cmd-> 1

我如何正确阅读cmd,这是正确的解释吗?

c bit-shift
2个回答
0
投票

您在这里

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef enum 
{
    GET = 0,
    SET = 1,
    UNDEF = 2,

} cmd_t;

struct  args 
{ 
    cmd_t cmd; 
    uint8_t value; 
    uint8_t id;
};

int main(){
    char buff[2];
    struct  args arguments;
    arguments.cmd=UNDEF;
    arguments.id=23;//256/4=64 range 0~63



    buff[0] = arguments.cmd;
    buff[0] += arguments.id << 2;
    buff[1] = arguments.value;



    printf("%d\n",buff[0]&0b11);
    printf("%d",(buff[0]&0b11111100)>>2);
    return 0;
}

0
投票

如果您只是想简单的方法,这是另一个选择union + struct

您可以在结构中定义每个成员多少位

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef enum 
{
    GET = 0,
    SET = 1,
    UNDEF = 2,

} cmd_t;


union args_v2{
    uint8_t raw[2];

    struct {
        uint8_t cmd: 2;//2bits
        uint8_t id: 6;//6bits
        uint8_t value:  8;//8bits
    };
};
int main(){


    union args_v2 arguments_2;
    arguments_2.id=32;
    arguments_2.cmd=UNDEF;
    arguments_2.value=77;
    printf("\nPack Size%d\n",sizeof(arguments_2));
    printf("\nRaw %d %d\n",arguments_2.raw[0],arguments_2.raw[1]);//130=32*4+2
    //
    printf("\nid:%d cmd:%d value:%d\n",arguments_2.id,arguments_2.cmd,arguments_2.value);





    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.