如何在lpBuffer中转换和连接位置以最终打印为整数的十六进制数?

问题描述 投票:0回答:1

我是C ++的新手。

我引用了10个以上类似问题的stackoverflow页面,但无论我尝试什么,我都无法推断出适合我特定问题的解决方案。

我有一些电子设备将数据馈送到串行端口,通过RealTerm和XCTU验证其正确性。 (长话短说我知道发送到端口的数据是正确的)

我正在使用CreateFile()/ dcb访问串行端口。 (我相当确定端口设置代码是正确的,但如果你想看到代码来验证你自己让我知道)(如果使用不同的方法访问串口将解决这个问题,请告诉我)

我在端口上执行的唯一操作是ReadFile()。 readFile()调用使用的lpBuffer设置为char []。我不知道为什么,但似乎char []的每个索引只接受一个字节的信息。出于调试目的,我使用:

cout << hex << setfill('0') << setw(2) ...

所以它会像这样打印到控制台:

lpBuffer in [...] = ...
lpBuffer in [11] = 03
lpBuffer in [12] = ff
lpBuffer in [...] = ...

我想使用连接两个字符串的概念,以便我得到:

03ff(1023)

我也更喜欢在变量中存储“连接”值的答案,而不更改存储在lpBuffer / char []中的信息(不是字面上连接它),并将值存储为整数。

我尝试过使用sprintf_s(),stringstream,转换为字符串并使用stoi。我发现的最接近的答案似乎不适用于lpBuffers(char []保存字节数据而不是实际字符?)并且还转换数组的所有索引,而不是特定的索引。

请帮帮忙,C ++奇才!

visual-c++ serial-port hex readfile data-conversion
1个回答
0
投票

虽然有些事情有点难看,但您通常要做的是定义一个按照您的预期描述数据的结构。因此,例如,假设您的数据是两个长整数(4个字节的项),后跟两个短路(2个字节的项)。

#pragma pack(1);
struct my_input {
    long data1;
    long data2;
    short data3;
    short data4;
    // more stuff here
};

然后,当您读入一个充满数据的缓冲区时,您可以执行以下操作:

my_input *in = (my_input *)&buffer[0];

然后你可以通过该结构的镜头看待数据(可以这么说),看看那些打算在那里的类型:

std::cout << in->data4;

在这种特殊情况下,您还有另外一个小问题需要处理:您收到的数据显然是以big-endian顺序或(有时称为)网络顺序。幸运的是,正常的网络库提供了一些函数来将网络顺序数据转换为您编译它的处理器所使用的数据,所以(在这种情况下)你想要这样的东西:

std::cout << ntohs(in->data4);

ntohs用于“短”(16位)值,ntohl用于长(32位)和(在大多数当前网络堆栈中)ntohll用于长(64位)值。

请注意pragma pack(1)。它告诉编译器不要在字段之间插入任何额外的填充。当您尝试匹配外部定义的结构时,如果在那里有任何填充,您通常希望显式插入它,而不是相信编译器会将其插入到您想要的位置。

© www.soinside.com 2019 - 2024. All rights reserved.