读/写二进制对象为十六进制?

时间:2013-07-03 15:56:45

标签: c++ serialization binary hex fstream

我需要将各种结构序列化为文件。 如果可能的话,我希望这些文件是纯ASCII。我可以为每个结构编写一些序列化器,但有数百个,包含floatdouble,我想准确表示。

我无法使用第三方序列化库,我没有时间编写数百个序列化程序。

如何对这些数据进行ASCII安全序列化? 还请流,我讨厌C风格的printf("%02x",data)

2 个答案:

答案 0 :(得分:2)

我在网上找到了这个解决方案,它解决了这个问题:

https://jdale88.wordpress.com/2009/09/24/c-anything-tofrom-a-hex-string/

转载如下:

#include <string>
#include <sstream>
#include <iomanip>


// ------------------------------------------------------------------
/*!
    Convert a block of data to a hex string
*/
void toHex(
    void *const data,                   //!< Data to convert
    const size_t dataLength,            //!< Length of the data to convert
    std::string &dest                   //!< Destination string
    )
{
    unsigned char       *byteData = reinterpret_cast<unsigned char*>(data);
    std::stringstream   hexStringStream;

    hexStringStream << std::hex << std::setfill('0');
    for(size_t index = 0; index < dataLength; ++index)
        hexStringStream << std::setw(2) << static_cast<int>(byteData[index]);
    dest = hexStringStream.str();
}


// ------------------------------------------------------------------
/*!
    Convert a hex string to a block of data
*/
void fromHex(
    const std::string &in,              //!< Input hex string
    void *const data                    //!< Data store
    )
{
    size_t          length      = in.length();
    unsigned char   *byteData   = reinterpret_cast<unsigned char*>(data);

    std::stringstream hexStringStream; hexStringStream >> std::hex;
    for(size_t strIndex = 0, dataIndex = 0; strIndex < length; ++dataIndex)
    {
        // Read out and convert the string two characters at a time
        const char tmpStr[3] = { in[strIndex++], in[strIndex++], 0 };

        // Reset and fill the string stream
        hexStringStream.clear();
        hexStringStream.str(tmpStr);

        // Do the conversion
        int tmpValue = 0;
        hexStringStream >> tmpValue;
        byteData[dataIndex] = static_cast<unsigned char>(tmpValue);
    }
}

这可以很容易地适应读/写文件流,虽然stringstream中使用的fromHex仍然是必需的,但转换必须一次完成两个读取字符。

答案 1 :(得分:0)

无论如何,你需要序列化代码 每种结构类型。你不能只是将一个结构点拷贝到 外部世界,期望它发挥作用。

如果你想要纯净的ascii,不要打扰十六进制。对于 序列化floatdouble,将输出流设置为 科学,float的精度为8,而16为精度 double。 (它将需要更多的字节,但它实际上会 的工作。)

其余的:如果结构是干净的,那么根据 一些内部编程指南,包含基本内容 类型,您应该能够直接解析它们。除此以外, 最简单的解决方案通常是设计一个非常简单的 描述符语言,描述其中的每个结构,并运行代码 生成器通过它来获取序列化代码。