Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
打包位并读取它们-C_C_Bit Shift - Fatal编程技术网

打包位并读取它们-C

打包位并读取它们-C,c,bit-shift,C,Bit Shift,以下是我发送到服务器的内容声明: typedef enum { GET = 0, SET = 1, UNDEF = 2, } cmd_t; struct args { cmd_t cmd; uint8_t value; uint8_t id; }; value属于uint8\u t类型,例如value42和id也是uint8\u t和value30cmd是我的typedef,例如GET也是0 我将此信息发送到如下打包的服务器: c

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

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

} cmd_t;

struct  args 
{ 
    cmd_t cmd; 
    uint8_t value; 
    uint8_t id;
};
value
属于
uint8\u t
类型,例如value
42
id
也是
uint8\u t
和value
30
cmd
是我的
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和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,这是正确的解释吗

给你

#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;
}
#包括
#包括
#包括
类型定义枚举
{
GET=0,
SET=1,
未定义=2,
}cmd_t;
结构参数
{ 
cmd_t cmd;
uint8_t值;
uint8_t id;
};
int main(){
字符buff[2];
结构参数;
arguments.cmd=unde;
arguments.id=23;//256/4=64范围0~63
buff[0]=arguments.cmd;
buff[0]+=arguments.id>2);
返回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;
}
#包括
#包括
#包括
类型定义枚举
{
GET=0,
SET=1,
未定义=2,
}cmd_t;
联合args_v2{
uint8_t原始[2];
结构{
uint8_t cmd:2;//2位
uint8\u t id:6;//6位
uint8_t值:8;//8位
};
};
int main(){
联合参数2;
参数_2.id=32;
参数_2.cmd=未定义;
参数_2.value=77;
printf(“\n包大小%d\n”,大小为(参数_2));
printf(“\nRaw%d%d\n”,参数_2.raw[0],参数_2.raw[1]);/130=32*4+2
//
printf(“\nid:%d cmd:%d value:%d\n”,参数\u 2.id,参数\u 2.cmd,参数\u 2.value);
返回0;
}

req[0]
中得到的值是多少?接收数据的代码在哪里?还有,
req
是如何声明的?如果是有符号类型,则移位可能无法按预期方式进行。同样,您可能希望将
buff
声明为
unsigned char buff[2]
uint8\u t buff[2]
。您还需要使用
屏蔽位
buff[0]
应该用
|=
@MaximSagaydachny构成:我不同意比特域,特别是当你需要在线路上有一个定义良好的协议时。如果你给了我们实际的输出,那会很有帮助。为什么要在右移之前应用掩码?不管怎样,你都会失去这些东西的。当你有位或运算时,当你把2个值组合成一个字节时,为什么要使用算术运算呢?因为在这种情况下不会引起任何问题。OP需要一个快速的答案,而不是一个好的答案,否则不会问这么简单的问题,我不想让他困惑如果他需要严格的,我不认为使用结构/联合/位域作为网络协议是一个好主意,因为如果客户机和服务器运行在不同的系统上(或使用不同的编译器构建),它们可能不会使用相同的布局,然后一切都会中断。你认为endian问题不大,因此,我声明使用uint8\u t数组不是uint16\u t,所以永远不要引起您的问题–Nate EldredgeI对此有经验,我认为这没有帮助。您不能保证任何两个编译器都会以相同的方式布局您的结构。在这种情况下,也许大多数常见的编译器都会这样做,但我仍然不认为这是一个好的做法。这就是为什么我使用uint_8而不是uint_16
#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;
}