所以我对C ++很陌生,并希望得到一些建设性的建议。
我目前正在开发一种用于科学火箭的遥测系统,该系统从仪器获取数据,从软件管道中存储数据,然后将这些数据发送到可用的串行端口。问题是仪器以XML格式传输数据包,例如:
<Sample Value="-4.80521e-012" />
<Sample Value="4.90272e-012" />
<Sample Value="3.49013e-011" />
<Sample Value="2.13785e-010" />
<Sample Value="2.38185e-010" />
<Sample Value="1.70573e-010" />
<Sample Value="1.16129e-011" />
这些临时存储在CreateFile / WriteFile(From serial port)创建的缓冲区中。探针本身不能发送除XML以外的其他格式,我需要将此隐式或显式转换为4字节十六进制(由于遥测要求),例如:
2c34b73f 2c1dfc77 2bbd69d2 a9220b89 a8a0cedf 290bc781...
我的问题是:有人能建议一个好方法吗?我应该尝试从流中删除子串集,还是在XML和十六进制之间进行转换的更简单方法?我再次注意到这是用C ++完成的。
致以最诚挚的问候,
Tarjei
答案 0 :(得分:0)
如果仪器中的数据只是非常简单的XML,您可能不需要一个完整的xml解析器,但您可以“手动”解析每一行。
对于每一行,提取表示值的子字符串:
<Sample Value="-4.80521e-012" />
变为
-4.80521e-012
然后使用"-4.80521e-012"
或sscanf
解析提取的子字符串strtof
以获得32位float
,最后将该浮点数转换为unsigned long
}和sprintf("08x",..)
它。
答案 1 :(得分:0)
该问题包括两个步骤:解析XML并将浮点数转换为IEEE 754中的表示形式,作为十六进制值。
对于解析XML ,有几个库可以简单地重用。您只需要考虑您的输入是否始终是完整的,有效的XML,或只是不能自立的片段。我不确定你的问题是否属实。
为了将浮点数转换为IEEE 754十六进制,大多数系统在内部表示IEEE 754中的浮点数。如果您的系统就是这种情况,则只需要找到表示。
您可以使用此功能(使用this question的输入):
std::string floatToIEEE754(float f) {
if (!std::numeric_limits<float>::is_iec559) {
std::cerr << "Not in IEEE 754 format!" << std::endl;
return "";
}
std::stringstream ss;
ss << std::hex << std::setw(2);
ss << static_cast<int> (reinterpret_cast<unsigned char*>(&f)[0]);
ss << static_cast<int> (reinterpret_cast<unsigned char*>(&f)[1]);
ss << static_cast<int> (reinterpret_cast<unsigned char*>(&f)[2]);
ss << static_cast<int> (reinterpret_cast<unsigned char*>(&f)[3]);
// Or to get it as int:
//int i;
//ss >> i;
//return i;
return ss.str();
}
奇怪的演员阵容是确保遵守语言的必要条件。严格地说,如果将一个指针类型转换为另一个指针类型(如int i = *((int*)&f);
),则C ++具有未定义的行为。只有char*
的强制转换才能保证正常工作。
如果您对系统没有严格要求,可以按如下方式简化方法:
std::string floatToIEEE754(float f) {
std::stringstream ss;
// Treat bits of float as an int, and print them as hex
ss << std::hex << *((int*) &f);
return ss.str();
}