C++ 如何访问整数的单个字节?

C++ 如何访问整数的单个字节?,c++,byte,bit,C++,Byte,Bit,对于指定的通信标准RTCM SC104 3.1,我需要将数据拆分为一对12位数据段。因此,对于给定的消息,我需要将消息类型编号放在第一个字节和第二个字节的一半上。然后我需要在第二个字节的一半开始一个ID整数,然后继续到第三个字节。这种模式一直延续到消息末尾,将20位、5位的其他整数和其他大小的整数切掉,实际上切掉了通常会填充整数值MSB端的0 我还没有看到一个清晰的定义,但我假设它必须以网络字节顺序输出,所以在复制位之前,我必须在内存中反转整数。 我对cpp还是很陌生,我想知道如何在内存中获得组

对于指定的通信标准RTCM SC104 3.1,我需要将数据拆分为一对12位数据段。因此,对于给定的消息,我需要将消息类型编号放在第一个字节和第二个字节的一半上。然后我需要在第二个字节的一半开始一个ID整数,然后继续到第三个字节。这种模式一直延续到消息末尾,将20位、5位的其他整数和其他大小的整数切掉,实际上切掉了通常会填充整数值MSB端的0

我还没有看到一个清晰的定义,但我假设它必须以网络字节顺序输出,所以在复制位之前,我必须在内存中反转整数。 我对cpp还是很陌生,我想知道如何在内存中获得组成整数的各个字节?如果我可以访问字节,那么我可以使用按位或将消息的字节从2个字节拆分为1个字节

以下是在添加数据之前构建消息的开始:

//build message 1002  gps 00111110 1010
    char buf1002[BUFFERSIZE];
    buf1002[0] = 0x3E; //00111110
    buf1002[1] = 0xA0; //10100000
//ref station id 12 bits of 16
//ex unsigned short m = 1100;
//m would be byte2 00000100 byte1 01001100
//buf1002[1] would be 10100100
//buf1002[2] would be 01001100
//reverse bit order for network after building? 
参考桩号将来自无符号短桩,因此为2字节整数。那么我如何从中读取一个字节呢?我是否从内存位置指针开始?如果是,那又怎样


任何帮助都将不胜感激

您可以将其双关为字节,例如:

const unsigned short s(1);
const char* const bytes(reinterpret_cast<const char*>(&s));

const char NaturalOrder[sizeof(s)] = {bytes[0],bytes[1]};
const char EndianFlipped[sizeof(s)] = {bytes[1],bytes[0]};
const无符号短s(1);
常量字符*常量字节(重新解释强制转换(&s));
const char NaturalOrder[sizeof(s)]={bytes[0],bytes[1]};
const char EndianFlipped[sizeof(s)]={字节[1],字节[0]};

(但也请参阅DMCKE关于构建体的自然大小的评论,并考虑使用固定宽度类型)。

< P>如果你的整型看起来像00001000个00000000×11000000个00110000(例如,我给每个单独的字节做空格),包含在int A:

中的例子。
int     a;
int     single_byte;

a = the_number;
你可以做一个函数,比如

int     get_byte_in_integer(int byte_number, int integer);
以便:

single_byte = get_byte_in_integer(1, a); // That would give you the 11000000 byte

int获取整数中的字节(int字节数,int整数)
{

return(integer>>(byte_number您可以使用位字段,如下所示-结尾有一些注意事项:

typedef union packet {
    struct {
        unsigned int msgno  : 12; // creates a 12 bit wide integral field
        unsigned int msgtype  : 12;
        unsigned int somefield2  : 3;
        unsigned int somefield3  : 5;
    } fields;

    unsigned char asbytes[4];
} packet;

...

packet p;
// fill it, by using the field side of the union
p.fields.msgno = 16;
p.fields.msgtype = 12;
p.fields.somefield2 = 6;
// and retrieving them as regular bytes
unsigned char abyte = p.asbytes[0];
abyte = p.asbytes[1];
// and so on

对我来说,主要的优点是可读性:所有操作的行为都类似于对更窄的整型变量的常规操作但是,如果您不需要针对多个体系结构、编译器或不同的Endian,它可以帮助您的程序更易于阅读。

请检查libswiftnav repo中实现的getbitu函数(下面复制的链接)。其思想是通过从ms位端提取,然后向最低有效位端移动,来提取跨多个字节压缩的值。它需要的输入是保存压缩值的缓冲区,即值的字节偏移量(相对于缓冲区的开头)以及要提取的值的位数。这些函数可以很容易地模板化,以支持返回压缩整数,而不是uint32…添加一些状态来保持当前偏移量(在后续对getbitu的调用中,偏移量会增加),通过反复发出getbitu()可以很容易地解压压缩消息中的所有数据字段根据特定的RTCM message schema.Portable,使值提取代码非常可读,并且可以立即解析新消息


阅读此处的第一个答案“参考站将来自无符号短码,因此为2字节整数。”短码不要求为2字节(尽管这是目前最常见的情况),它至少需要16位。你可以使用
uint16\u t
来强制执行此操作。我喜欢你的想法。这是一种完全不同的方法,可以将整个消息构建在一个数组中,我可以将其发送到套接字。我花了一段时间才弄清楚它在做什么。
typedef union packet {
    struct {
        unsigned int msgno  : 12; // creates a 12 bit wide integral field
        unsigned int msgtype  : 12;
        unsigned int somefield2  : 3;
        unsigned int somefield3  : 5;
    } fields;

    unsigned char asbytes[4];
} packet;

...

packet p;
// fill it, by using the field side of the union
p.fields.msgno = 16;
p.fields.msgtype = 12;
p.fields.somefield2 = 6;
// and retrieving them as regular bytes
unsigned char abyte = p.asbytes[0];
abyte = p.asbytes[1];
// and so on