我是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 ++向导!
答案 0 :(得分: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;
在这种特殊情况下,您还有一点其他需要处理的问题:接收到的数据显然是按大端顺序或(有时称为)网络顺序排列的。幸运的是,普通的网络库提供了一些功能,可将网络顺序数据转换为您为其编译的处理器所使用的数据,因此(在这种情况下)您需要这样的东西:
std::cout << ntohs(in->data4);
ntohs
代表“短”(16位)值,ntohl
代表长(32位)值,(在大多数当前的网络堆栈中)ntohll
代表长值长(64位)值。
请注意pragma pack(1)
。它告诉编译器不要在字段之间插入任何额外的填充。当您尝试匹配外部定义的结构时,如果在其中存在任何填充,则通常要显式地插入它,而不是相信编译器会在所需的位置插入它。