将XML流转换为十六进制

时间:2014-04-08 08:21:00

标签: c++ xml hex

所以我对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

2 个答案:

答案 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();
}